// Copyright 2024 The langsvr Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

////////////////////////////////////////////////////////////////////////////////
// File generated by 'tools/cmd/gen' using the template:
//   include/langsvr/lsp/lsp.h.tmpl
//
// To regenerate run: 'go run ./tools/cmd/gen'
//
//                       Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
#ifndef LANGSVR_LSP_LSP_H_
#define LANGSVR_LSP_LSP_H_

#include <string>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <vector>

#include "langsvr/lsp/decode.h"
#include "langsvr/lsp/encode.h"
#include "langsvr/lsp/message_kind.h"
#include "langsvr/lsp/primitives.h"
#include "langsvr/one_of.h"
#include "langsvr/optional.h"

////////////////////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////////////////////
namespace langsvr::lsp {
enum class SemanticTokenTypes;
enum class SemanticTokenModifiers;
enum class DocumentDiagnosticReportKind;
enum class ErrorCodes;
enum class LSPErrorCodes;
enum class FoldingRangeKind;
enum class SymbolKind;
enum class SymbolTag;
enum class UniquenessLevel;
enum class MonikerKind;
enum class InlayHintKind;
enum class MessageType;
enum class TextDocumentSyncKind;
enum class TextDocumentSaveReason;
enum class CompletionItemKind;
enum class CompletionItemTag;
enum class InsertTextFormat;
enum class InsertTextMode;
enum class DocumentHighlightKind;
enum class CodeActionKind;
enum class TraceValues;
enum class MarkupKind;
enum class InlineCompletionTriggerKind;
enum class PositionEncodingKind;
enum class FileChangeType;
enum class WatchKind;
enum class DiagnosticSeverity;
enum class DiagnosticTag;
enum class CompletionTriggerKind;
enum class SignatureHelpTriggerKind;
enum class CodeActionTriggerKind;
enum class FileOperationPatternKind;
enum class NotebookCellKind;
enum class ResourceOperationKind;
enum class FailureHandlingKind;
enum class PrepareSupportDefaultBehavior;
enum class TokenFormat;
struct TextDocumentIdentifier;
struct Position;
struct TextDocumentPositionParams;
struct ImplementationParams;
struct Range;
struct Location;
struct TextDocumentRegistrationOptions;
struct ImplementationOptions;
struct ImplementationRegistrationOptions;
struct TypeDefinitionParams;
struct TypeDefinitionOptions;
struct TypeDefinitionRegistrationOptions;
struct WorkspaceFolder;
struct WorkspaceFoldersChangeEvent;
struct DidChangeWorkspaceFoldersParams;
struct ConfigurationItem;
struct ConfigurationParams;
struct DocumentColorParams;
struct Color;
struct ColorInformation;
struct DocumentColorOptions;
struct DocumentColorRegistrationOptions;
struct ColorPresentationParams;
struct TextEdit;
struct ColorPresentation;
struct WorkDoneProgressOptions;
struct FoldingRangeParams;
struct FoldingRange;
struct FoldingRangeOptions;
struct FoldingRangeRegistrationOptions;
struct DeclarationParams;
struct DeclarationOptions;
struct DeclarationRegistrationOptions;
struct SelectionRangeParams;
struct SelectionRange;
struct SelectionRangeOptions;
struct SelectionRangeRegistrationOptions;
struct WorkDoneProgressCreateParams;
struct WorkDoneProgressCancelParams;
struct CallHierarchyPrepareParams;
struct CallHierarchyItem;
struct CallHierarchyOptions;
struct CallHierarchyRegistrationOptions;
struct CallHierarchyIncomingCallsParams;
struct CallHierarchyIncomingCall;
struct CallHierarchyOutgoingCallsParams;
struct CallHierarchyOutgoingCall;
struct SemanticTokensParams;
struct SemanticTokens;
struct SemanticTokensPartialResult;
struct SemanticTokensLegend;
struct SemanticTokensFullDelta;
struct SemanticTokensOptions;
struct SemanticTokensRegistrationOptions;
struct SemanticTokensDeltaParams;
struct SemanticTokensEdit;
struct SemanticTokensDelta;
struct SemanticTokensDeltaPartialResult;
struct SemanticTokensRangeParams;
struct ShowDocumentParams;
struct ShowDocumentResult;
struct LinkedEditingRangeParams;
struct LinkedEditingRanges;
struct LinkedEditingRangeOptions;
struct LinkedEditingRangeRegistrationOptions;
struct FileCreate;
struct CreateFilesParams;
struct ResourceOperation;
struct DeleteFileOptions;
struct DeleteFile;
struct RenameFileOptions;
struct RenameFile;
struct CreateFileOptions;
struct CreateFile;
struct OptionalVersionedTextDocumentIdentifier;
struct AnnotatedTextEdit;
struct TextDocumentEdit;
struct ChangeAnnotation;
struct WorkspaceEdit;
struct FileOperationPatternOptions;
struct FileOperationPattern;
struct FileOperationFilter;
struct FileOperationRegistrationOptions;
struct FileRename;
struct RenameFilesParams;
struct FileDelete;
struct DeleteFilesParams;
struct MonikerParams;
struct Moniker;
struct MonikerOptions;
struct MonikerRegistrationOptions;
struct TypeHierarchyPrepareParams;
struct TypeHierarchyItem;
struct TypeHierarchyOptions;
struct TypeHierarchyRegistrationOptions;
struct TypeHierarchySupertypesParams;
struct TypeHierarchySubtypesParams;
struct InlineValueContext;
struct InlineValueParams;
struct InlineValueOptions;
struct InlineValueRegistrationOptions;
struct InlayHintParams;
struct MarkupContent;
struct Command;
struct InlayHintLabelPart;
struct InlayHint;
struct InlayHintOptions;
struct InlayHintRegistrationOptions;
struct DocumentDiagnosticParams;
struct UnchangedDocumentDiagnosticReport;
struct CodeDescription;
struct DiagnosticRelatedInformation;
struct Diagnostic;
struct FullDocumentDiagnosticReport;
struct DocumentDiagnosticReportPartialResult;
struct DiagnosticServerCancellationData;
struct DiagnosticOptions;
struct DiagnosticRegistrationOptions;
struct PreviousResultId;
struct WorkspaceDiagnosticParams;
struct WorkspaceDiagnosticReport;
struct WorkspaceDiagnosticReportPartialResult;
struct ExecutionSummary;
struct NotebookCell;
struct NotebookDocument;
struct TextDocumentItem;
struct DidOpenNotebookDocumentParams;
struct VersionedNotebookDocumentIdentifier;
struct NotebookCellArrayChange;
struct NotebookDocumentCellChangeStructure;
struct VersionedTextDocumentIdentifier;
struct NotebookDocumentCellContentChanges;
struct NotebookDocumentCellChanges;
struct NotebookDocumentChangeEvent;
struct DidChangeNotebookDocumentParams;
struct NotebookDocumentIdentifier;
struct DidSaveNotebookDocumentParams;
struct DidCloseNotebookDocumentParams;
struct SelectedCompletionInfo;
struct InlineCompletionContext;
struct InlineCompletionParams;
struct StringValue;
struct InlineCompletionItem;
struct InlineCompletionList;
struct InlineCompletionOptions;
struct InlineCompletionRegistrationOptions;
struct Registration;
struct RegistrationParams;
struct Unregistration;
struct UnregistrationParams;
struct ClientInfo;
struct ChangeAnnotationsSupportOptions;
struct WorkspaceEditClientCapabilities;
struct DidChangeConfigurationClientCapabilities;
struct DidChangeWatchedFilesClientCapabilities;
struct ClientSymbolKindOptions;
struct ClientSymbolTagOptions;
struct ClientSymbolResolveOptions;
struct WorkspaceSymbolClientCapabilities;
struct ExecuteCommandClientCapabilities;
struct SemanticTokensWorkspaceClientCapabilities;
struct CodeLensWorkspaceClientCapabilities;
struct FileOperationClientCapabilities;
struct InlineValueWorkspaceClientCapabilities;
struct InlayHintWorkspaceClientCapabilities;
struct DiagnosticWorkspaceClientCapabilities;
struct FoldingRangeWorkspaceClientCapabilities;
struct WorkspaceClientCapabilities;
struct TextDocumentSyncClientCapabilities;
struct CompletionItemTagOptions;
struct ClientCompletionItemResolveOptions;
struct ClientCompletionItemInsertTextModeOptions;
struct ClientCompletionItemOptions;
struct ClientCompletionItemOptionsKind;
struct CompletionListCapabilities;
struct CompletionClientCapabilities;
struct HoverClientCapabilities;
struct ClientSignatureParameterInformationOptions;
struct ClientSignatureInformationOptions;
struct SignatureHelpClientCapabilities;
struct DeclarationClientCapabilities;
struct DefinitionClientCapabilities;
struct TypeDefinitionClientCapabilities;
struct ImplementationClientCapabilities;
struct ReferenceClientCapabilities;
struct DocumentHighlightClientCapabilities;
struct DocumentSymbolClientCapabilities;
struct ClientCodeActionKindOptions;
struct ClientCodeActionLiteralOptions;
struct ClientCodeActionResolveOptions;
struct CodeActionClientCapabilities;
struct CodeLensClientCapabilities;
struct DocumentLinkClientCapabilities;
struct DocumentColorClientCapabilities;
struct DocumentFormattingClientCapabilities;
struct DocumentRangeFormattingClientCapabilities;
struct DocumentOnTypeFormattingClientCapabilities;
struct RenameClientCapabilities;
struct ClientFoldingRangeKindOptions;
struct ClientFoldingRangeOptions;
struct FoldingRangeClientCapabilities;
struct SelectionRangeClientCapabilities;
struct ClientDiagnosticsTagOptions;
struct PublishDiagnosticsClientCapabilities;
struct CallHierarchyClientCapabilities;
struct ClientSemanticTokensRequestFullDelta;
struct ClientSemanticTokensRequestOptions;
struct SemanticTokensClientCapabilities;
struct LinkedEditingRangeClientCapabilities;
struct MonikerClientCapabilities;
struct TypeHierarchyClientCapabilities;
struct InlineValueClientCapabilities;
struct ClientInlayHintResolveOptions;
struct InlayHintClientCapabilities;
struct DiagnosticClientCapabilities;
struct InlineCompletionClientCapabilities;
struct TextDocumentClientCapabilities;
struct NotebookDocumentSyncClientCapabilities;
struct NotebookDocumentClientCapabilities;
struct ClientShowMessageActionItemOptions;
struct ShowMessageRequestClientCapabilities;
struct ShowDocumentClientCapabilities;
struct WindowClientCapabilities;
struct StaleRequestSupportOptions;
struct RegularExpressionsClientCapabilities;
struct MarkdownClientCapabilities;
struct GeneralClientCapabilities;
struct ClientCapabilities;
struct InitializeParamsBase;
struct WorkspaceFoldersInitializeParams;
struct InitializeParams;
struct SaveOptions;
struct TextDocumentSyncOptions;
struct NotebookCellLanguage;
struct NotebookDocumentFilterWithCells;
struct NotebookDocumentFilterWithNotebook;
struct NotebookDocumentSyncOptions;
struct NotebookDocumentSyncRegistrationOptions;
struct ServerCompletionItemOptions;
struct CompletionOptions;
struct HoverOptions;
struct SignatureHelpOptions;
struct DefinitionOptions;
struct ReferenceOptions;
struct DocumentHighlightOptions;
struct DocumentSymbolOptions;
struct CodeActionOptions;
struct CodeLensOptions;
struct DocumentLinkOptions;
struct WorkspaceSymbolOptions;
struct DocumentFormattingOptions;
struct DocumentRangeFormattingOptions;
struct DocumentOnTypeFormattingOptions;
struct RenameOptions;
struct ExecuteCommandOptions;
struct WorkspaceFoldersServerCapabilities;
struct FileOperationOptions;
struct WorkspaceOptions;
struct ServerCapabilities;
struct ServerInfo;
struct InitializeResult;
struct InitializeError;
struct InitializedParams;
struct DidChangeConfigurationParams;
struct DidChangeConfigurationRegistrationOptions;
struct ShowMessageParams;
struct MessageActionItem;
struct ShowMessageRequestParams;
struct LogMessageParams;
struct DidOpenTextDocumentParams;
struct DidChangeTextDocumentParams;
struct TextDocumentChangeRegistrationOptions;
struct DidCloseTextDocumentParams;
struct DidSaveTextDocumentParams;
struct TextDocumentSaveRegistrationOptions;
struct WillSaveTextDocumentParams;
struct FileEvent;
struct DidChangeWatchedFilesParams;
struct FileSystemWatcher;
struct DidChangeWatchedFilesRegistrationOptions;
struct PublishDiagnosticsParams;
struct CompletionContext;
struct CompletionParams;
struct CompletionItemLabelDetails;
struct InsertReplaceEdit;
struct CompletionItem;
struct EditRangeWithInsertReplace;
struct CompletionItemDefaults;
struct CompletionList;
struct CompletionRegistrationOptions;
struct HoverParams;
struct Hover;
struct HoverRegistrationOptions;
struct ParameterInformation;
struct SignatureInformation;
struct SignatureHelp;
struct SignatureHelpContext;
struct SignatureHelpParams;
struct SignatureHelpRegistrationOptions;
struct DefinitionParams;
struct DefinitionRegistrationOptions;
struct ReferenceContext;
struct ReferenceParams;
struct ReferenceRegistrationOptions;
struct DocumentHighlightParams;
struct DocumentHighlight;
struct DocumentHighlightRegistrationOptions;
struct DocumentSymbolParams;
struct BaseSymbolInformation;
struct SymbolInformation;
struct DocumentSymbol;
struct DocumentSymbolRegistrationOptions;
struct CodeActionContext;
struct CodeActionParams;
struct CodeActionDisabled;
struct CodeAction;
struct CodeActionRegistrationOptions;
struct WorkspaceSymbolParams;
struct LocationUriOnly;
struct WorkspaceSymbol;
struct WorkspaceSymbolRegistrationOptions;
struct CodeLensParams;
struct CodeLens;
struct CodeLensRegistrationOptions;
struct DocumentLinkParams;
struct DocumentLink;
struct DocumentLinkRegistrationOptions;
struct FormattingOptions;
struct DocumentFormattingParams;
struct DocumentFormattingRegistrationOptions;
struct DocumentRangeFormattingParams;
struct DocumentRangeFormattingRegistrationOptions;
struct DocumentRangesFormattingParams;
struct DocumentOnTypeFormattingParams;
struct DocumentOnTypeFormattingRegistrationOptions;
struct RenameParams;
struct RenameRegistrationOptions;
struct PrepareRenameParams;
struct ExecuteCommandParams;
struct ExecuteCommandRegistrationOptions;
struct ApplyWorkspaceEditParams;
struct ApplyWorkspaceEditResult;
struct WorkDoneProgressBegin;
struct WorkDoneProgressReport;
struct WorkDoneProgressEnd;
struct SetTraceParams;
struct LogTraceParams;
struct CancelParams;
struct ProgressParams;
struct WorkDoneProgressParams;
struct PartialResultParams;
struct LocationLink;
struct StaticRegistrationOptions;
struct InlineValueText;
struct InlineValueVariableLookup;
struct InlineValueEvaluatableExpression;
struct RelatedFullDocumentDiagnosticReport;
struct RelatedUnchangedDocumentDiagnosticReport;
struct PrepareRenamePlaceholder;
struct PrepareRenameDefaultBehavior;
struct WorkspaceFullDocumentDiagnosticReport;
struct WorkspaceUnchangedDocumentDiagnosticReport;
struct TextDocumentContentChangePartial;
struct TextDocumentContentChangeWholeDocument;
struct MarkedStringWithLanguage;
struct NotebookCellTextDocumentFilter;
struct RelativePattern;
struct TextDocumentFilterLanguage;
struct TextDocumentFilterScheme;
struct TextDocumentFilterPattern;
struct NotebookDocumentFilterNotebookType;
struct NotebookDocumentFilterScheme;
struct NotebookDocumentFilterPattern;
struct LSPAny;
}  // namespace langsvr::lsp

namespace langsvr::lsp {

////////////////////////////////////////////////////////////////////////////////
// Type aliases
////////////////////////////////////////////////////////////////////////////////

/// A notebook document filter denotes a notebook document by different properties. The properties
/// will be match against the notebook's URI (same as with documents)
///
/// @since 3.17.0
using NotebookDocumentFilter = OneOf<lsp::NotebookDocumentFilterNotebookType,
                                     lsp::NotebookDocumentFilterScheme,
                                     lsp::NotebookDocumentFilterPattern>;

/// The glob pattern to watch relative to the base path. Glob patterns can have the following
/// syntax: - `*` to match one or more characters in a path segment - `?` to match on one character
/// in a path segment - `**` to match any number of path segments, including none - `{}` to group
/// conditions (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files) - `[]` to
/// declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on
/// `example.0`, `example.1`, …) - `[!...]` to negate a range of characters to match in a path
/// segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
///
/// @since 3.17.0
using Pattern = String;

/// A document filter denotes a document by different properties like the TextDocument.languageId
/// language, the Uri.scheme scheme of its resource, or a glob-pattern that is applied to the
/// TextDocument.fileName path. Glob patterns can have the following syntax: - `*` to match one or
/// more characters in a path segment - `?` to match on one character in a path segment - `**` to
/// match any number of path segments, including none - `{}` to group sub patterns into an OR
/// expression. (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files) - `[]` to
/// declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on
/// `example.0`, `example.1`, …) - `[!...]` to negate a range of characters to match in a path
/// segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
///
/// Example: A language filter that applies to typescript files on disk: `{ language: 'typescript',
/// scheme: 'file' }`
///
/// Example: A language filter that applies to all package.json paths: `{ language: 'json', pattern:
/// '**package.json' }`
///
/// @since 3.17.0
using TextDocumentFilter = OneOf<lsp::TextDocumentFilterLanguage,
                                 lsp::TextDocumentFilterScheme,
                                 lsp::TextDocumentFilterPattern>;

/// The glob pattern. Either a string pattern or a relative pattern.
///
/// @since 3.17.0
using GlobPattern = OneOf<lsp::Pattern, lsp::RelativePattern>;

/// LSP object definition.
///
/// @since 3.17.0
using LSPObject = std::unordered_map<String, lsp::LSPAny>;

/// LSP arrays.
///
/// @since 3.17.0
using LSPArray = std::vector<lsp::LSPAny>;

/// A document filter describes a top level text document or a notebook cell document.
///
/// @since 3.17.0 - proposed support for NotebookCellTextDocumentFilter.
using DocumentFilter = OneOf<lsp::TextDocumentFilter, lsp::NotebookCellTextDocumentFilter>;

/// MarkedString can be used to render human readable text. It is either a markdown string or a
/// code-block that provides a language and a code snippet. The language identifier is semantically
/// equal to the optional language identifier in fenced code blocks in GitHub issues. See
/// https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting The
/// pair of a language and a value is an equivalent to markdown: ```${language} ${value} ``` Note
/// that markdown strings will be sanitized - that means html will be escaped.
///
/// Deprecated: use MarkupContent instead.
using MarkedString = OneOf<String, lsp::MarkedStringWithLanguage>;

/// An event describing a change to a text document. If only a text is provided it is considered to
/// be the full content of the document.
using TextDocumentContentChangeEvent =
    OneOf<lsp::TextDocumentContentChangePartial, lsp::TextDocumentContentChangeWholeDocument>;

/// A workspace diagnostic document report.
///
/// @since 3.17.0
using WorkspaceDocumentDiagnosticReport = OneOf<lsp::WorkspaceFullDocumentDiagnosticReport,
                                                lsp::WorkspaceUnchangedDocumentDiagnosticReport>;

/// An identifier to refer to a change annotation stored with a workspace edit.
using ChangeAnnotationIdentifier = String;

/// No documentation available
using ProgressToken = OneOf<Integer, String>;

/// A document selector is the combination of one or many document filters.
///
/// Example: `let sel:DocumentSelector = [{ language: 'typescript' }, { language: 'json', pattern:
/// '**∕tsconfig.json' }]`; The use of a string as a document filter is deprecated
///
/// @since 3.16.0.
using DocumentSelector = std::vector<lsp::DocumentFilter>;

/// No documentation available
using PrepareRenameResult =
    OneOf<lsp::Range, lsp::PrepareRenamePlaceholder, lsp::PrepareRenameDefaultBehavior>;

/// The result of a document diagnostic pull request. A report can either be a full report
/// containing all diagnostics for the requested document or an unchanged report indicating that
/// nothing has changed in terms of diagnostics in comparison to the last pull request.
///
/// @since 3.17.0
using DocumentDiagnosticReport =
    OneOf<lsp::RelatedFullDocumentDiagnosticReport, lsp::RelatedUnchangedDocumentDiagnosticReport>;

/// Inline value information can be provided by different means: - directly as a text value (class
/// InlineValueText). - as a name to use for a variable lookup (class InlineValueVariableLookup) -
/// as an evaluatable expression (class InlineValueEvaluatableExpression) The InlineValue types
/// combines all inline value types into one type.
///
/// @since 3.17.0
using InlineValue = OneOf<lsp::InlineValueText,
                          lsp::InlineValueVariableLookup,
                          lsp::InlineValueEvaluatableExpression>;

/// Information about where a symbol is declared. Provides additional metadata over normal Location
/// location declarations, including the range of the declaring symbol. Servers should prefer
/// returning `DeclarationLink` over `Declaration` if supported by the client.
using DeclarationLink = lsp::LocationLink;

/// The declaration of a symbol representation as one or many Location locations.
using Declaration = OneOf<lsp::Location, std::vector<lsp::Location>>;

/// Information about where a symbol is defined. Provides additional metadata over normal Location
/// location definitions, including the range of the defining symbol
using DefinitionLink = lsp::LocationLink;

/// The definition of a symbol represented as one or many Location locations. For most programming
/// languages there is only one location at which a symbol is defined. Servers should prefer
/// returning `DefinitionLink` over `Definition` if supported by the client.
using Definition = OneOf<lsp::Location, std::vector<lsp::Location>>;

/// The LSP any type. Please note that strictly speaking a property with the value `undefined` can't
/// be converted into JSON preserving the property name. However for convenience it is allowed and
/// assumed that all these properties are optional as well.
///
/// @since 3.17.0
struct LSPAny
    : OneOf<lsp::LSPObject, lsp::LSPArray, String, Integer, Uinteger, Decimal, Boolean, Null> {};

////////////////////////////////////////////////////////////////////////////////
// Enums
////////////////////////////////////////////////////////////////////////////////

/// A set of predefined token types. This set is not fixed an clients can specify additional token
/// types via the corresponding client capabilities.
///
/// @since 3.16.0
enum class SemanticTokenTypes {
    /// No documentation available
    kNamespace /* = "namespace" */,

    /// Represents a generic type. Acts as a fallback for types which can't be mapped to a specific
    /// type like class or enum.
    kType /* = "type" */,

    /// No documentation available
    kClass /* = "class" */,

    /// No documentation available
    kEnum /* = "enum" */,

    /// No documentation available
    kInterface /* = "interface" */,

    /// No documentation available
    kStruct /* = "struct" */,

    /// No documentation available
    kTypeParameter /* = "typeParameter" */,

    /// No documentation available
    kParameter /* = "parameter" */,

    /// No documentation available
    kVariable /* = "variable" */,

    /// No documentation available
    kProperty /* = "property" */,

    /// No documentation available
    kEnumMember /* = "enumMember" */,

    /// No documentation available
    kEvent /* = "event" */,

    /// No documentation available
    kFunction /* = "function" */,

    /// No documentation available
    kMethod /* = "method" */,

    /// No documentation available
    kMacro /* = "macro" */,

    /// No documentation available
    kKeyword /* = "keyword" */,

    /// No documentation available
    kModifier /* = "modifier" */,

    /// No documentation available
    kComment /* = "comment" */,

    /// No documentation available
    kString /* = "string" */,

    /// No documentation available
    kNumber /* = "number" */,

    /// No documentation available
    kRegexp /* = "regexp" */,

    /// No documentation available
    kOperator /* = "operator" */,

    /// @since 3.17.0
    kDecorator /* = "decorator" */,
};

Result<SuccessType> Decode(const json::Value& v, SemanticTokenTypes& out);
Result<const json::Value*> Encode(SemanticTokenTypes in, json::Builder& b);

/// A set of predefined token modifiers. This set is not fixed an clients can specify additional
/// token types via the corresponding client capabilities.
///
/// @since 3.16.0
enum class SemanticTokenModifiers {
    /// No documentation available
    kDeclaration /* = "declaration" */,

    /// No documentation available
    kDefinition /* = "definition" */,

    /// No documentation available
    kReadonly /* = "readonly" */,

    /// No documentation available
    kStatic /* = "static" */,

    /// No documentation available
    kDeprecated /* = "deprecated" */,

    /// No documentation available
    kAbstract /* = "abstract" */,

    /// No documentation available
    kAsync /* = "async" */,

    /// No documentation available
    kModification /* = "modification" */,

    /// No documentation available
    kDocumentation /* = "documentation" */,

    /// No documentation available
    kDefaultLibrary /* = "defaultLibrary" */,
};

Result<SuccessType> Decode(const json::Value& v, SemanticTokenModifiers& out);
Result<const json::Value*> Encode(SemanticTokenModifiers in, json::Builder& b);

/// The document diagnostic report kinds.
///
/// @since 3.17.0
enum class DocumentDiagnosticReportKind {
    /// A diagnostic report with a full set of problems.
    kFull /* = "full" */,

    /// A report indicating that the last returned report is still accurate.
    kUnchanged /* = "unchanged" */,
};

Result<SuccessType> Decode(const json::Value& v, DocumentDiagnosticReportKind& out);
Result<const json::Value*> Encode(DocumentDiagnosticReportKind in, json::Builder& b);

/// Predefined error codes.
enum class ErrorCodes {
    /// No documentation available
    kParseError /* = -32700 */,

    /// No documentation available
    kInvalidRequest /* = -32600 */,

    /// No documentation available
    kMethodNotFound /* = -32601 */,

    /// No documentation available
    kInvalidParams /* = -32602 */,

    /// No documentation available
    kInternalError /* = -32603 */,

    /// Error code indicating that a server received a notification or request before the server has
    /// received the `initialize` request.
    kServerNotInitialized /* = -32002 */,

    /// No documentation available
    kUnknownErrorCode /* = -32001 */,
};

Result<SuccessType> Decode(const json::Value& v, ErrorCodes& out);
Result<const json::Value*> Encode(ErrorCodes in, json::Builder& b);

/// No documentation available
enum class LSPErrorCodes {
    /// A request failed but it was syntactically correct, e.g the method name was known and the
    /// parameters were valid. The error message should contain human readable information about why
    /// the request failed.
    ///
    /// @since 3.17.0
    kRequestFailed /* = -32803 */,

    /// The server cancelled the request. This error code should only be used for requests that
    /// explicitly support being server cancellable.
    ///
    /// @since 3.17.0
    kServerCancelled /* = -32802 */,

    /// The server detected that the content of a document got modified outside normal conditions. A
    /// server should NOT send this error code if it detects a content change in it unprocessed
    /// messages. The result even computed on an older state might still be useful for the client.
    /// If a client decides that a result is not of any use anymore the client should cancel the
    /// request.
    kContentModified /* = -32801 */,

    /// The client has canceled a request and a server as detected the cancel.
    kRequestCancelled /* = -32800 */,
};

Result<SuccessType> Decode(const json::Value& v, LSPErrorCodes& out);
Result<const json::Value*> Encode(LSPErrorCodes in, json::Builder& b);

/// A set of predefined range kinds.
enum class FoldingRangeKind {
    /// Folding range for a comment
    kComment /* = "comment" */,

    /// Folding range for an import or include
    kImports /* = "imports" */,

    /// Folding range for a region (e.g. `#region`)
    kRegion /* = "region" */,
};

Result<SuccessType> Decode(const json::Value& v, FoldingRangeKind& out);
Result<const json::Value*> Encode(FoldingRangeKind in, json::Builder& b);

/// A symbol kind.
enum class SymbolKind {
    /// No documentation available
    kFile /* = 1 */,

    /// No documentation available
    kModule /* = 2 */,

    /// No documentation available
    kNamespace /* = 3 */,

    /// No documentation available
    kPackage /* = 4 */,

    /// No documentation available
    kClass /* = 5 */,

    /// No documentation available
    kMethod /* = 6 */,

    /// No documentation available
    kProperty /* = 7 */,

    /// No documentation available
    kField /* = 8 */,

    /// No documentation available
    kConstructor /* = 9 */,

    /// No documentation available
    kEnum /* = 10 */,

    /// No documentation available
    kInterface /* = 11 */,

    /// No documentation available
    kFunction /* = 12 */,

    /// No documentation available
    kVariable /* = 13 */,

    /// No documentation available
    kConstant /* = 14 */,

    /// No documentation available
    kString /* = 15 */,

    /// No documentation available
    kNumber /* = 16 */,

    /// No documentation available
    kBoolean /* = 17 */,

    /// No documentation available
    kArray /* = 18 */,

    /// No documentation available
    kObject /* = 19 */,

    /// No documentation available
    kKey /* = 20 */,

    /// No documentation available
    kNull /* = 21 */,

    /// No documentation available
    kEnumMember /* = 22 */,

    /// No documentation available
    kStruct /* = 23 */,

    /// No documentation available
    kEvent /* = 24 */,

    /// No documentation available
    kOperator /* = 25 */,

    /// No documentation available
    kTypeParameter /* = 26 */,
};

Result<SuccessType> Decode(const json::Value& v, SymbolKind& out);
Result<const json::Value*> Encode(SymbolKind in, json::Builder& b);

/// Symbol tags are extra annotations that tweak the rendering of a symbol.
///
/// @since 3.16
enum class SymbolTag {
    /// Render a symbol as obsolete, usually using a strike-out.
    kDeprecated /* = 1 */,
};

Result<SuccessType> Decode(const json::Value& v, SymbolTag& out);
Result<const json::Value*> Encode(SymbolTag in, json::Builder& b);

/// Moniker uniqueness level to define scope of the moniker.
///
/// @since 3.16.0
enum class UniquenessLevel {
    /// The moniker is only unique inside a document
    kDocument /* = "document" */,

    /// The moniker is unique inside a project for which a dump got created
    kProject /* = "project" */,

    /// The moniker is unique inside the group to which a project belongs
    kGroup /* = "group" */,

    /// The moniker is unique inside the moniker scheme.
    kScheme /* = "scheme" */,

    /// The moniker is globally unique
    kGlobal /* = "global" */,
};

Result<SuccessType> Decode(const json::Value& v, UniquenessLevel& out);
Result<const json::Value*> Encode(UniquenessLevel in, json::Builder& b);

/// The moniker kind.
///
/// @since 3.16.0
enum class MonikerKind {
    /// The moniker represent a symbol that is imported into a project
    kImport /* = "import" */,

    /// The moniker represents a symbol that is exported from a project
    kExport /* = "export" */,

    /// The moniker represents a symbol that is local to a project (e.g. a local variable of a
    /// function, a class not visible outside the project, ...)
    kLocal /* = "local" */,
};

Result<SuccessType> Decode(const json::Value& v, MonikerKind& out);
Result<const json::Value*> Encode(MonikerKind in, json::Builder& b);

/// Inlay hint kinds.
///
/// @since 3.17.0
enum class InlayHintKind {
    /// An inlay hint that for a type annotation.
    kType /* = 1 */,

    /// An inlay hint that is for a parameter.
    kParameter /* = 2 */,
};

Result<SuccessType> Decode(const json::Value& v, InlayHintKind& out);
Result<const json::Value*> Encode(InlayHintKind in, json::Builder& b);

/// The message type
enum class MessageType {
    /// An error message.
    kError /* = 1 */,

    /// A warning message.
    kWarning /* = 2 */,

    /// An information message.
    kInfo /* = 3 */,

    /// A log message.
    kLog /* = 4 */,

    /// A debug message.
    ///
    /// @since 3.18.0
    kDebug /* = 5 */,
};

Result<SuccessType> Decode(const json::Value& v, MessageType& out);
Result<const json::Value*> Encode(MessageType in, json::Builder& b);

/// Defines how the host (editor) should sync document changes to the language server.
enum class TextDocumentSyncKind {
    /// Documents should not be synced at all.
    kNone /* = 0 */,

    /// Documents are synced by always sending the full content of the document.
    kFull /* = 1 */,

    /// Documents are synced by sending the full content on open. After that only incremental
    /// updates to the document are send.
    kIncremental /* = 2 */,
};

Result<SuccessType> Decode(const json::Value& v, TextDocumentSyncKind& out);
Result<const json::Value*> Encode(TextDocumentSyncKind in, json::Builder& b);

/// Represents reasons why a text document is saved.
enum class TextDocumentSaveReason {
    /// Manually triggered, e.g. by the user pressing save, by starting debugging, or by an API
    /// call.
    kManual /* = 1 */,

    /// Automatic after a delay.
    kAfterDelay /* = 2 */,

    /// When the editor lost focus.
    kFocusOut /* = 3 */,
};

Result<SuccessType> Decode(const json::Value& v, TextDocumentSaveReason& out);
Result<const json::Value*> Encode(TextDocumentSaveReason in, json::Builder& b);

/// The kind of a completion entry.
enum class CompletionItemKind {
    /// No documentation available
    kText /* = 1 */,

    /// No documentation available
    kMethod /* = 2 */,

    /// No documentation available
    kFunction /* = 3 */,

    /// No documentation available
    kConstructor /* = 4 */,

    /// No documentation available
    kField /* = 5 */,

    /// No documentation available
    kVariable /* = 6 */,

    /// No documentation available
    kClass /* = 7 */,

    /// No documentation available
    kInterface /* = 8 */,

    /// No documentation available
    kModule /* = 9 */,

    /// No documentation available
    kProperty /* = 10 */,

    /// No documentation available
    kUnit /* = 11 */,

    /// No documentation available
    kValue /* = 12 */,

    /// No documentation available
    kEnum /* = 13 */,

    /// No documentation available
    kKeyword /* = 14 */,

    /// No documentation available
    kSnippet /* = 15 */,

    /// No documentation available
    kColor /* = 16 */,

    /// No documentation available
    kFile /* = 17 */,

    /// No documentation available
    kReference /* = 18 */,

    /// No documentation available
    kFolder /* = 19 */,

    /// No documentation available
    kEnumMember /* = 20 */,

    /// No documentation available
    kConstant /* = 21 */,

    /// No documentation available
    kStruct /* = 22 */,

    /// No documentation available
    kEvent /* = 23 */,

    /// No documentation available
    kOperator /* = 24 */,

    /// No documentation available
    kTypeParameter /* = 25 */,
};

Result<SuccessType> Decode(const json::Value& v, CompletionItemKind& out);
Result<const json::Value*> Encode(CompletionItemKind in, json::Builder& b);

/// Completion item tags are extra annotations that tweak the rendering of a completion item.
///
/// @since 3.15.0
enum class CompletionItemTag {
    /// Render a completion as obsolete, usually using a strike-out.
    kDeprecated /* = 1 */,
};

Result<SuccessType> Decode(const json::Value& v, CompletionItemTag& out);
Result<const json::Value*> Encode(CompletionItemTag in, json::Builder& b);

/// Defines whether the insert text in a completion item should be interpreted as plain text or a
/// snippet.
enum class InsertTextFormat {
    /// The primary text to be inserted is treated as a plain string.
    kPlainText /* = 1 */,

    /// The primary text to be inserted is treated as a snippet. A snippet can define tab stops and
    /// placeholders with `$1`, `$2` and `${3:foo}`. `$0` defines the final tab stop, it defaults to
    /// the end of the snippet. Placeholders with equal identifiers are linked, that is typing in
    /// one will update others too. See also:
    /// https://microsoft.github.io/language-server-protocol/specifications/specification-current/#snippet_syntax
    kSnippet /* = 2 */,
};

Result<SuccessType> Decode(const json::Value& v, InsertTextFormat& out);
Result<const json::Value*> Encode(InsertTextFormat in, json::Builder& b);

/// How whitespace and indentation is handled during completion item insertion.
///
/// @since 3.16.0
enum class InsertTextMode {
    /// The insertion or replace strings is taken as it is. If the value is multi line the lines
    /// below the cursor will be inserted using the indentation defined in the string value. The
    /// client will not apply any kind of adjustments to the string.
    kAsIs /* = 1 */,

    /// The editor adjusts leading whitespace of new lines so that they match the indentation up to
    /// the cursor of the line for which the item is accepted. Consider a line like this:
    /// <2tabs><cursor><3tabs>foo. Accepting a multi line completion item is indented using 2 tabs
    /// and all following lines inserted will be indented using 2 tabs as well.
    kAdjustIndentation /* = 2 */,
};

Result<SuccessType> Decode(const json::Value& v, InsertTextMode& out);
Result<const json::Value*> Encode(InsertTextMode in, json::Builder& b);

/// A document highlight kind.
enum class DocumentHighlightKind {
    /// A textual occurrence.
    kText /* = 1 */,

    /// Read-access of a symbol, like reading a variable.
    kRead /* = 2 */,

    /// Write-access of a symbol, like writing to a variable.
    kWrite /* = 3 */,
};

Result<SuccessType> Decode(const json::Value& v, DocumentHighlightKind& out);
Result<const json::Value*> Encode(DocumentHighlightKind in, json::Builder& b);

/// A set of predefined code action kinds
enum class CodeActionKind {
    /// Empty kind.
    kEmpty /* = "" */,

    /// Base kind for quickfix actions: 'quickfix'
    kQuickFix /* = "quickfix" */,

    /// Base kind for refactoring actions: 'refactor'
    kRefactor /* = "refactor" */,

    /// Base kind for refactoring extraction actions: 'refactor.extract' Example extract actions: -
    /// Extract method - Extract function - Extract variable - Extract interface from class - ...
    kRefactorExtract /* = "refactor.extract" */,

    /// Base kind for refactoring inline actions: 'refactor.inline' Example inline actions: - Inline
    /// function - Inline variable - Inline constant - ...
    kRefactorInline /* = "refactor.inline" */,

    /// Base kind for refactoring rewrite actions: 'refactor.rewrite' Example rewrite actions: -
    /// Convert JavaScript function to class - Add or remove parameter - Encapsulate field - Make
    /// method static - Move method to base class - ...
    kRefactorRewrite /* = "refactor.rewrite" */,

    /// Base kind for source actions: `source` Source code actions apply to the entire file.
    kSource /* = "source" */,

    /// Base kind for an organize imports source action: `source.organizeImports`
    kSourceOrganizeImports /* = "source.organizeImports" */,

    /// Base kind for auto-fix source actions: `source.fixAll`. Fix all actions automatically fix
    /// errors that have a clear fix that do not require user input. They should not suppress errors
    /// or perform unsafe fixes such as generating new types or classes.
    ///
    /// @since 3.15.0
    kSourceFixAll /* = "source.fixAll" */,
};

Result<SuccessType> Decode(const json::Value& v, CodeActionKind& out);
Result<const json::Value*> Encode(CodeActionKind in, json::Builder& b);

/// No documentation available
enum class TraceValues {
    /// Turn tracing off.
    kOff /* = "off" */,

    /// Trace messages only.
    kMessages /* = "messages" */,

    /// Verbose message tracing.
    kVerbose /* = "verbose" */,
};

Result<SuccessType> Decode(const json::Value& v, TraceValues& out);
Result<const json::Value*> Encode(TraceValues in, json::Builder& b);

/// Describes the content type that a client supports in various result literals like `Hover`,
/// `ParameterInfo` or `CompletionItem`. Please note that `MarkupKinds` must not start with a `$`.
/// This kinds are reserved for internal usage.
enum class MarkupKind {
    /// Plain text is supported as a content format
    kPlainText /* = "plaintext" */,

    /// Markdown is supported as a content format
    kMarkdown /* = "markdown" */,
};

Result<SuccessType> Decode(const json::Value& v, MarkupKind& out);
Result<const json::Value*> Encode(MarkupKind in, json::Builder& b);

/// Describes how an InlineCompletionItemProvider inline completion provider was triggered.
///
/// @since 3.18.0
///
/// Proposed in:
enum class InlineCompletionTriggerKind {
    /// Completion was triggered explicitly by a user gesture.
    kInvoked /* = 0 */,

    /// Completion was triggered automatically while editing.
    kAutomatic /* = 1 */,
};

Result<SuccessType> Decode(const json::Value& v, InlineCompletionTriggerKind& out);
Result<const json::Value*> Encode(InlineCompletionTriggerKind in, json::Builder& b);

/// A set of predefined position encoding kinds.
///
/// @since 3.17.0
enum class PositionEncodingKind {
    /// Character offsets count UTF-8 code units (e.g. bytes).
    kUTF8 /* = "utf-8" */,

    /// Character offsets count UTF-16 code units. This is the default and must always be supported
    /// by servers
    kUTF16 /* = "utf-16" */,

    /// Character offsets count UTF-32 code units. Implementation note: these are the same as
    /// Unicode codepoints, so this `PositionEncodingKind` may also be used for an encoding-agnostic
    /// representation of character offsets.
    kUTF32 /* = "utf-32" */,
};

Result<SuccessType> Decode(const json::Value& v, PositionEncodingKind& out);
Result<const json::Value*> Encode(PositionEncodingKind in, json::Builder& b);

/// The file event type
enum class FileChangeType {
    /// The file got created.
    kCreated /* = 1 */,

    /// The file got changed.
    kChanged /* = 2 */,

    /// The file got deleted.
    kDeleted /* = 3 */,
};

Result<SuccessType> Decode(const json::Value& v, FileChangeType& out);
Result<const json::Value*> Encode(FileChangeType in, json::Builder& b);

/// No documentation available
enum class WatchKind {
    /// Interested in create events.
    kCreate /* = 1 */,

    /// Interested in change events
    kChange /* = 2 */,

    /// Interested in delete events
    kDelete /* = 4 */,
};

Result<SuccessType> Decode(const json::Value& v, WatchKind& out);
Result<const json::Value*> Encode(WatchKind in, json::Builder& b);

/// The diagnostic's severity.
enum class DiagnosticSeverity {
    /// Reports an error.
    kError /* = 1 */,

    /// Reports a warning.
    kWarning /* = 2 */,

    /// Reports an information.
    kInformation /* = 3 */,

    /// Reports a hint.
    kHint /* = 4 */,
};

Result<SuccessType> Decode(const json::Value& v, DiagnosticSeverity& out);
Result<const json::Value*> Encode(DiagnosticSeverity in, json::Builder& b);

/// The diagnostic tags.
///
/// @since 3.15.0
enum class DiagnosticTag {
    /// Unused or unnecessary code. Clients are allowed to render diagnostics with this tag faded
    /// out instead of having an error squiggle.
    kUnnecessary /* = 1 */,

    /// Deprecated or obsolete code. Clients are allowed to rendered diagnostics with this tag
    /// strike through.
    kDeprecated /* = 2 */,
};

Result<SuccessType> Decode(const json::Value& v, DiagnosticTag& out);
Result<const json::Value*> Encode(DiagnosticTag in, json::Builder& b);

/// How a completion was triggered
enum class CompletionTriggerKind {
    /// Completion was triggered by typing an identifier (24x7 code complete), manual invocation
    /// (e.g Ctrl+Space) or via API.
    kInvoked /* = 1 */,

    /// Completion was triggered by a trigger character specified by the `triggerCharacters`
    /// properties of the `CompletionRegistrationOptions`.
    kTriggerCharacter /* = 2 */,

    /// Completion was re-triggered as current completion list is incomplete
    kTriggerForIncompleteCompletions /* = 3 */,
};

Result<SuccessType> Decode(const json::Value& v, CompletionTriggerKind& out);
Result<const json::Value*> Encode(CompletionTriggerKind in, json::Builder& b);

/// How a signature help was triggered.
///
/// @since 3.15.0
enum class SignatureHelpTriggerKind {
    /// Signature help was invoked manually by the user or by a command.
    kInvoked /* = 1 */,

    /// Signature help was triggered by a trigger character.
    kTriggerCharacter /* = 2 */,

    /// Signature help was triggered by the cursor moving or by the document content changing.
    kContentChange /* = 3 */,
};

Result<SuccessType> Decode(const json::Value& v, SignatureHelpTriggerKind& out);
Result<const json::Value*> Encode(SignatureHelpTriggerKind in, json::Builder& b);

/// The reason why code actions were requested.
///
/// @since 3.17.0
enum class CodeActionTriggerKind {
    /// Code actions were explicitly requested by the user or by an extension.
    kInvoked /* = 1 */,

    /// Code actions were requested automatically. This typically happens when current selection in
    /// a file changes, but can also be triggered when file content changes.
    kAutomatic /* = 2 */,
};

Result<SuccessType> Decode(const json::Value& v, CodeActionTriggerKind& out);
Result<const json::Value*> Encode(CodeActionTriggerKind in, json::Builder& b);

/// A pattern kind describing if a glob pattern matches a file a folder or both.
///
/// @since 3.16.0
enum class FileOperationPatternKind {
    /// The pattern matches a file only.
    kFile /* = "file" */,

    /// The pattern matches a folder only.
    kFolder /* = "folder" */,
};

Result<SuccessType> Decode(const json::Value& v, FileOperationPatternKind& out);
Result<const json::Value*> Encode(FileOperationPatternKind in, json::Builder& b);

/// A notebook cell kind.
///
/// @since 3.17.0
enum class NotebookCellKind {
    /// A markup-cell is formatted source that is used for display.
    kMarkup /* = 1 */,

    /// A code-cell is source code.
    kCode /* = 2 */,
};

Result<SuccessType> Decode(const json::Value& v, NotebookCellKind& out);
Result<const json::Value*> Encode(NotebookCellKind in, json::Builder& b);

/// No documentation available
enum class ResourceOperationKind {
    /// Supports creating new files and folders.
    kCreate /* = "create" */,

    /// Supports renaming existing files and folders.
    kRename /* = "rename" */,

    /// Supports deleting existing files and folders.
    kDelete /* = "delete" */,
};

Result<SuccessType> Decode(const json::Value& v, ResourceOperationKind& out);
Result<const json::Value*> Encode(ResourceOperationKind in, json::Builder& b);

/// No documentation available
enum class FailureHandlingKind {
    /// Applying the workspace change is simply aborted if one of the changes provided fails. All
    /// operations executed before the failing operation stay executed.
    kAbort /* = "abort" */,

    /// All operations are executed transactional. That means they either all succeed or no changes
    /// at all are applied to the workspace.
    kTransactional /* = "transactional" */,

    /// If the workspace edit contains only textual file changes they are executed transactional. If
    /// resource changes (create, rename or delete file) are part of the change the failure handling
    /// strategy is abort.
    kTextOnlyTransactional /* = "textOnlyTransactional" */,

    /// The client tries to undo the operations already executed. But there is no guarantee that
    /// this is succeeding.
    kUndo /* = "undo" */,
};

Result<SuccessType> Decode(const json::Value& v, FailureHandlingKind& out);
Result<const json::Value*> Encode(FailureHandlingKind in, json::Builder& b);

/// No documentation available
enum class PrepareSupportDefaultBehavior {
    /// The client's default behavior is to select the identifier according the to language's syntax
    /// rule.
    kIdentifier /* = 1 */,
};

Result<SuccessType> Decode(const json::Value& v, PrepareSupportDefaultBehavior& out);
Result<const json::Value*> Encode(PrepareSupportDefaultBehavior in, json::Builder& b);

/// No documentation available
enum class TokenFormat {
    /// No documentation available
    kRelative /* = "relative" */,
};

Result<SuccessType> Decode(const json::Value& v, TokenFormat& out);
Result<const json::Value*> Encode(TokenFormat in, json::Builder& b);

////////////////////////////////////////////////////////////////////////////////
// Structures
////////////////////////////////////////////////////////////////////////////////

/// A literal to identify a text document in the client.
struct TextDocumentIdentifier {
    /// The text document's uri.
    DocumentUri uri{};
};

/// Position in a text document expressed as zero-based line and character offset. Prior to 3.17 the
/// offsets were always based on a UTF-16 string representation. So a string of the form `a𐐀b` the
/// character offset of the character `a` is 0, the character offset of `𐐀` is 1 and the character
/// offset of b is 3 since `𐐀` is represented using two code units in UTF-16. Since 3.17 clients and
/// servers can agree on a different string encoding representation (e.g. UTF-8). The client
/// announces it's supported encoding via the client capability
/// [`general.positionEncodings`](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#clientCapabilities).
/// The value is an array of position encodings the client supports, with decreasing preference
/// (e.g. the encoding at index `0` is the most preferred one). To stay backwards compatible the
/// only mandatory encoding is UTF-16 represented via the string `utf-16`. The server can pick one
/// of the encodings offered by the client and signals that encoding back to the client via the
/// initialize result's property
/// [`capabilities.positionEncoding`](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#serverCapabilities).
/// If the string value `utf-16` is missing from the client's capability `general.positionEncodings`
/// servers can safely assume that the client supports UTF-16. If the server omits the position
/// encoding in its initialize result the encoding defaults to the string value `utf-16`.
/// Implementation considerations: since the conversion from one encoding into another requires the
/// content of the file / line the conversion is best done where the file is read which is usually
/// on the server side. Positions are line end character agnostic. So you can not specify a position
/// that denotes `\r|\n` or `\n|` where `|` represents the character offset.
///
/// @since 3.17.0 - support for negotiated position encoding.
struct Position {
    /// Line position in a document (zero-based). If a line number is greater than the number of
    /// lines in a document, it defaults back to the number of lines in the document. If a line
    /// number is negative, it defaults to 0.
    Uinteger line{};

    /// Character offset on a line in a document (zero-based). The meaning of this offset is
    /// determined by the negotiated `PositionEncodingKind`. If the character value is greater than
    /// the line length it defaults back to the line length.
    Uinteger character{};
};

/// A parameter literal used in requests to pass a text document and a position inside that
/// document.
struct TextDocumentPositionParams {
    /// The text document.
    lsp::TextDocumentIdentifier text_document{};

    /// The position inside the text document.
    lsp::Position position{};
};

/// No documentation available
struct ImplementationParams : lsp::TextDocumentPositionParams {};

/// A range in a text document expressed as (zero-based) start and end positions. If you want to
/// specify a range that contains a line including the line ending character(s) then use an end
/// position denoting the start of the next line. For example: ```ts {   start: { line: 5,
/// character: 23 }   end : { line 6, character : 0 } } ```
struct Range {
    /// The range's start position.
    lsp::Position start{};

    /// The range's end position.
    lsp::Position end{};
};

/// Represents a location inside a resource, such as a line inside a text file.
struct Location {
    /// No documentation available
    DocumentUri uri{};

    /// No documentation available
    lsp::Range range{};
};

/// General text document registration options.
struct TextDocumentRegistrationOptions {
    /// A document selector to identify the scope of the registration. If set to null the document
    /// selector provided on the client side will be used.
    OneOf<lsp::DocumentSelector, Null> document_selector{};
};

/// No documentation available
struct ImplementationOptions {};

/// No documentation available
struct ImplementationRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                           lsp::ImplementationOptions {};

/// No documentation available
struct TypeDefinitionParams : lsp::TextDocumentPositionParams {};

/// No documentation available
struct TypeDefinitionOptions {};

/// No documentation available
struct TypeDefinitionRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                           lsp::TypeDefinitionOptions {};

/// A workspace folder inside a client.
struct WorkspaceFolder {
    /// The associated URI for this workspace folder.
    Uri uri{};

    /// The name of the workspace folder. Used to refer to this workspace folder in the user
    /// interface.
    String name{};
};

/// The workspace folder change event.
struct WorkspaceFoldersChangeEvent {
    /// The array of added workspace folders
    std::vector<lsp::WorkspaceFolder> added{};

    /// The array of the removed workspace folders
    std::vector<lsp::WorkspaceFolder> removed{};
};

/// The parameters of a `workspace/didChangeWorkspaceFolders` notification.
struct DidChangeWorkspaceFoldersParams {
    /// The actual workspace folder change event.
    lsp::WorkspaceFoldersChangeEvent event{};
};

/// No documentation available
struct ConfigurationItem {
    /// The scope to get the configuration section for.
    Optional<Uri> scope_uri;

    /// The configuration section asked for.
    Optional<String> section;
};

/// The parameters of a configuration request.
struct ConfigurationParams {
    /// No documentation available
    std::vector<lsp::ConfigurationItem> items{};
};

/// Parameters for a DocumentColorRequest.
struct DocumentColorParams {
    /// The text document.
    lsp::TextDocumentIdentifier text_document{};
};

/// Represents a color in RGBA space.
struct Color {
    /// The red component of this color in the range [0-1].
    Decimal red{};

    /// The green component of this color in the range [0-1].
    Decimal green{};

    /// The blue component of this color in the range [0-1].
    Decimal blue{};

    /// The alpha component of this color in the range [0-1].
    Decimal alpha{};
};

/// Represents a color range from a document.
struct ColorInformation {
    /// The range in the document where this color appears.
    lsp::Range range{};

    /// The actual color value for this color range.
    lsp::Color color{};
};

/// No documentation available
struct DocumentColorOptions {};

/// No documentation available
struct DocumentColorRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                          lsp::DocumentColorOptions {};

/// Parameters for a ColorPresentationRequest.
struct ColorPresentationParams {
    /// The text document.
    lsp::TextDocumentIdentifier text_document{};

    /// The color to request presentations for.
    lsp::Color color{};

    /// The range where the color would be inserted. Serves as a context.
    lsp::Range range{};
};

/// A text edit applicable to a text document.
struct TextEdit {
    /// The range of the text document to be manipulated. To insert text into a document create a
    /// range where start === end.
    lsp::Range range{};

    /// The string to be inserted. For delete operations use an empty string.
    String new_text{};
};

/// No documentation available
struct ColorPresentation {
    /// The label of this color presentation. It will be shown on the color picker header. By
    /// default this is also the text that is inserted when selecting this color presentation.
    String label{};

    /// An TextEdit edit which is applied to a document when selecting this presentation for the
    /// color. When `falsy` the ColorPresentation.label label is used.
    Optional<lsp::TextEdit> text_edit;

    /// An optional array of additional TextEdit text edits that are applied when selecting this
    /// color presentation. Edits must not overlap with the main ColorPresentation.textEdit edit nor
    /// with themselves.
    Optional<std::vector<lsp::TextEdit>> additional_text_edits;
};

/// No documentation available
struct WorkDoneProgressOptions {
    /// No documentation available
    Optional<Boolean> work_done_progress;
};

/// Parameters for a FoldingRangeRequest.
struct FoldingRangeParams {
    /// The text document.
    lsp::TextDocumentIdentifier text_document{};
};

/// Represents a folding range. To be valid, start and end line must be bigger than zero and smaller
/// than the number of lines in the document. Clients are free to ignore invalid ranges.
struct FoldingRange {
    /// The zero-based start line of the range to fold. The folded area starts after the line's last
    /// character. To be valid, the end must be zero or larger and smaller than the number of lines
    /// in the document.
    Uinteger start_line{};

    /// The zero-based character offset from where the folded range starts. If not defined, defaults
    /// to the length of the start line.
    Optional<Uinteger> start_character;

    /// The zero-based end line of the range to fold. The folded area ends with the line's last
    /// character. To be valid, the end must be zero or larger and smaller than the number of lines
    /// in the document.
    Uinteger end_line{};

    /// The zero-based character offset before the folded range ends. If not defined, defaults to
    /// the length of the end line.
    Optional<Uinteger> end_character;

    /// Describes the kind of the folding range such as `comment' or 'region'. The kind is used to
    /// categorize folding ranges and used by commands like 'Fold all comments'. See
    /// FoldingRangeKind for an enumeration of standardized kinds.
    Optional<lsp::FoldingRangeKind> kind;

    /// The text that the client should show when the specified range is collapsed. If not defined
    /// or not supported by the client, a default will be chosen by the client.
    ///
    /// @since 3.17.0
    Optional<String> collapsed_text;
};

/// No documentation available
struct FoldingRangeOptions {};

/// No documentation available
struct FoldingRangeRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                         lsp::FoldingRangeOptions {};

/// No documentation available
struct DeclarationParams : lsp::TextDocumentPositionParams {};

/// No documentation available
struct DeclarationOptions {};

/// No documentation available
struct DeclarationRegistrationOptions : lsp::DeclarationOptions,
                                        lsp::TextDocumentRegistrationOptions {};

/// A parameter literal used in selection range requests.
struct SelectionRangeParams {
    /// The text document.
    lsp::TextDocumentIdentifier text_document{};

    /// The positions inside the text document.
    std::vector<lsp::Position> positions{};
};

/// A selection range represents a part of a selection hierarchy. A selection range may have a
/// parent selection range that contains it.
struct SelectionRange {
    /// The Range range of this selection range.
    lsp::Range range{};

    /// The parent selection range containing this range. Therefore `parent.range` must contain
    /// `this.range`.
    Optional<lsp::SelectionRange> parent;
};

/// No documentation available
struct SelectionRangeOptions {};

/// No documentation available
struct SelectionRangeRegistrationOptions : lsp::SelectionRangeOptions,
                                           lsp::TextDocumentRegistrationOptions {};

/// No documentation available
struct WorkDoneProgressCreateParams {
    /// The token to be used to report progress.
    lsp::ProgressToken token{};
};

/// No documentation available
struct WorkDoneProgressCancelParams {
    /// The token to be used to report progress.
    lsp::ProgressToken token{};
};

/// The parameter of a `textDocument/prepareCallHierarchy` request.
///
/// @since 3.16.0
struct CallHierarchyPrepareParams : lsp::TextDocumentPositionParams {};

/// Represents programming constructs like functions or constructors in the context of call
/// hierarchy.
///
/// @since 3.16.0
struct CallHierarchyItem {
    /// The name of this item.
    String name{};

    /// The kind of this item.
    lsp::SymbolKind kind{};

    /// Tags for this item.
    Optional<std::vector<lsp::SymbolTag>> tags;

    /// More detail for this item, e.g. the signature of a function.
    Optional<String> detail;

    /// The resource identifier of this item.
    DocumentUri uri{};

    /// The range enclosing this symbol not including leading/trailing whitespace but everything
    /// else, e.g. comments and code.
    lsp::Range range{};

    /// The range that should be selected and revealed when this symbol is being picked, e.g. the
    /// name of a function. Must be contained by the CallHierarchyItem.range `range`.
    lsp::Range selection_range{};

    /// A data entry field that is preserved between a call hierarchy prepare and incoming calls or
    /// outgoing calls requests.
    Optional<lsp::LSPAny> data;
};

/// Call hierarchy options used during static registration.
///
/// @since 3.16.0
struct CallHierarchyOptions {};

/// Call hierarchy options used during static or dynamic registration.
///
/// @since 3.16.0
struct CallHierarchyRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                          lsp::CallHierarchyOptions {};

/// The parameter of a `callHierarchy/incomingCalls` request.
///
/// @since 3.16.0
struct CallHierarchyIncomingCallsParams {
    /// No documentation available
    lsp::CallHierarchyItem item{};
};

/// Represents an incoming call, e.g. a caller of a method or constructor.
///
/// @since 3.16.0
struct CallHierarchyIncomingCall {
    /// The item that makes the call.
    lsp::CallHierarchyItem from{};

    /// The ranges at which the calls appear. This is relative to the caller denoted by
    /// CallHierarchyIncomingCall.from `this.from`.
    std::vector<lsp::Range> from_ranges{};
};

/// The parameter of a `callHierarchy/outgoingCalls` request.
///
/// @since 3.16.0
struct CallHierarchyOutgoingCallsParams {
    /// No documentation available
    lsp::CallHierarchyItem item{};
};

/// Represents an outgoing call, e.g. calling a getter from a method or a method from a constructor
/// etc.
///
/// @since 3.16.0
struct CallHierarchyOutgoingCall {
    /// The item that is called.
    lsp::CallHierarchyItem to{};

    /// The range at which this item is called. This is the range relative to the caller, e.g the
    /// item passed to CallHierarchyItemProvider.provideCallHierarchyOutgoingCalls
    /// `provideCallHierarchyOutgoingCalls` and not CallHierarchyOutgoingCall.to `this.to`.
    std::vector<lsp::Range> from_ranges{};
};

/// @since 3.16.0
struct SemanticTokensParams {
    /// The text document.
    lsp::TextDocumentIdentifier text_document{};
};

/// @since 3.16.0
struct SemanticTokens {
    /// An optional result id. If provided and clients support delta updating the client will
    /// include the result id in the next semantic token request. A server can then instead of
    /// computing all semantic tokens again simply send a delta.
    Optional<String> result_id;

    /// The actual tokens.
    std::vector<Uinteger> data{};
};

/// @since 3.16.0
struct SemanticTokensPartialResult {
    /// No documentation available
    std::vector<Uinteger> data{};
};

/// @since 3.16.0
struct SemanticTokensLegend {
    /// The token types a server uses.
    std::vector<String> token_types{};

    /// The token modifiers a server uses.
    std::vector<String> token_modifiers{};
};

/// Semantic tokens options to support deltas for full documents
///
/// @since 3.18.0
///
/// Proposed in:
struct SemanticTokensFullDelta {
    /// The server supports deltas for full documents.
    Optional<Boolean> delta;
};

/// @since 3.16.0
struct SemanticTokensOptions {
    /// No documentation available
    struct Range {};

    /// The legend used by the server
    lsp::SemanticTokensLegend legend{};

    /// Server supports providing semantic tokens for a specific range of a document.
    Optional<OneOf<Boolean, lsp::SemanticTokensOptions::Range>> range;

    /// Server supports providing semantic tokens for a full document.
    Optional<OneOf<Boolean, lsp::SemanticTokensFullDelta>> full;
};

/// @since 3.16.0
struct SemanticTokensRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                           lsp::SemanticTokensOptions {};

/// @since 3.16.0
struct SemanticTokensDeltaParams {
    /// The text document.
    lsp::TextDocumentIdentifier text_document{};

    /// The result id of a previous response. The result Id can either point to a full response or a
    /// delta response depending on what was received last.
    String previous_result_id{};
};

/// @since 3.16.0
struct SemanticTokensEdit {
    /// The start offset of the edit.
    Uinteger start{};

    /// The count of elements to remove.
    Uinteger delete_count{};

    /// The elements to insert.
    Optional<std::vector<Uinteger>> data;
};

/// @since 3.16.0
struct SemanticTokensDelta {
    /// No documentation available
    Optional<String> result_id;

    /// The semantic token edits to transform a previous result into a new result.
    std::vector<lsp::SemanticTokensEdit> edits{};
};

/// @since 3.16.0
struct SemanticTokensDeltaPartialResult {
    /// No documentation available
    std::vector<lsp::SemanticTokensEdit> edits{};
};

/// @since 3.16.0
struct SemanticTokensRangeParams {
    /// The text document.
    lsp::TextDocumentIdentifier text_document{};

    /// The range the semantic tokens are requested for.
    lsp::Range range{};
};

/// Params to show a resource in the UI.
///
/// @since 3.16.0
struct ShowDocumentParams {
    /// The uri to show.
    Uri uri{};

    /// Indicates to show the resource in an external program. To show, for example,
    /// `https://code.visualstudio.com/` in the default WEB browser set `external` to `true`.
    Optional<Boolean> external;

    /// An optional property to indicate whether the editor showing the document should take focus
    /// or not. Clients might ignore this property if an external program is started.
    Optional<Boolean> take_focus;

    /// An optional selection range if the document is a text document. Clients might ignore the
    /// property if an external program is started or the file is not a text file.
    Optional<lsp::Range> selection;
};

/// The result of a showDocument request.
///
/// @since 3.16.0
struct ShowDocumentResult {
    /// A boolean indicating if the show was successful.
    Boolean success{};
};

/// No documentation available
struct LinkedEditingRangeParams : lsp::TextDocumentPositionParams {};

/// The result of a linked editing range request.
///
/// @since 3.16.0
struct LinkedEditingRanges {
    /// A list of ranges that can be edited together. The ranges must have identical length and
    /// contain identical text content. The ranges cannot overlap.
    std::vector<lsp::Range> ranges{};

    /// An optional word pattern (regular expression) that describes valid contents for the given
    /// ranges. If no pattern is provided, the client configuration's word pattern will be used.
    Optional<String> word_pattern;
};

/// No documentation available
struct LinkedEditingRangeOptions {};

/// No documentation available
struct LinkedEditingRangeRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                               lsp::LinkedEditingRangeOptions {};

/// Represents information on a file/folder create.
///
/// @since 3.16.0
struct FileCreate {
    /// A file:// URI for the location of the file/folder being created.
    String uri{};
};

/// The parameters sent in notifications/requests for user-initiated creation of files.
///
/// @since 3.16.0
struct CreateFilesParams {
    /// An array of all files/folders created in this operation.
    std::vector<lsp::FileCreate> files{};
};

/// A generic resource operation.
struct ResourceOperation {
    /// The resource operation kind.
    String kind{};

    /// An optional annotation identifier describing the operation.
    ///
    /// @since 3.16.0
    Optional<lsp::ChangeAnnotationIdentifier> annotation_id;
};

/// Delete file options
struct DeleteFileOptions {
    /// Delete the content recursively if a folder is denoted.
    Optional<Boolean> recursive;

    /// Ignore the operation if the file doesn't exist.
    Optional<Boolean> ignore_if_not_exists;
};

/// Delete file operation
struct DeleteFile : lsp::ResourceOperation {
    /// The structure type identifier
    static constexpr std::string_view kKind = "delete";

    /// The file to delete.
    DocumentUri uri{};

    /// Delete options.
    Optional<lsp::DeleteFileOptions> options;
};

/// Rename file options
struct RenameFileOptions {
    /// Overwrite target if existing. Overwrite wins over `ignoreIfExists`
    Optional<Boolean> overwrite;

    /// Ignores if target exists.
    Optional<Boolean> ignore_if_exists;
};

/// Rename file operation
struct RenameFile : lsp::ResourceOperation {
    /// The structure type identifier
    static constexpr std::string_view kKind = "rename";

    /// The old (existing) location.
    DocumentUri old_uri{};

    /// The new location.
    DocumentUri new_uri{};

    /// Rename options.
    Optional<lsp::RenameFileOptions> options;
};

/// Options to create a file.
struct CreateFileOptions {
    /// Overwrite existing file. Overwrite wins over `ignoreIfExists`
    Optional<Boolean> overwrite;

    /// Ignore if exists.
    Optional<Boolean> ignore_if_exists;
};

/// Create file operation.
struct CreateFile : lsp::ResourceOperation {
    /// The structure type identifier
    static constexpr std::string_view kKind = "create";

    /// The resource to create.
    DocumentUri uri{};

    /// Additional options
    Optional<lsp::CreateFileOptions> options;
};

/// A text document identifier to optionally denote a specific version of a text document.
struct OptionalVersionedTextDocumentIdentifier : lsp::TextDocumentIdentifier {
    /// The version number of this document. If a versioned text document identifier is sent from
    /// the server to the client and the file is not open in the editor (the server has not received
    /// an open notification before) the server can send `null` to indicate that the version is
    /// unknown and the content on disk is the truth (as specified with document content ownership).
    OneOf<Integer, Null> version{};
};

/// A special text edit with an additional change annotation.
///
/// @since 3.16.0.
struct AnnotatedTextEdit : lsp::TextEdit {
    /// The actual identifier of the change annotation
    lsp::ChangeAnnotationIdentifier annotation_id{};
};

/// Describes textual changes on a text document. A TextDocumentEdit describes all changes on a
/// document version Si and after they are applied move the document to version Si+1. So the creator
/// of a TextDocumentEdit doesn't need to sort the array of edits or do any kind of ordering.
/// However the edits must be non overlapping.
struct TextDocumentEdit {
    /// The text document to change.
    lsp::OptionalVersionedTextDocumentIdentifier text_document{};

    /// The edits to be applied.
    ///
    /// @since 3.16.0 - support for AnnotatedTextEdit. This is guarded using a client capability.
    std::vector<OneOf<lsp::TextEdit, lsp::AnnotatedTextEdit>> edits{};
};

/// Additional information that describes document changes.
///
/// @since 3.16.0
struct ChangeAnnotation {
    /// A human-readable string describing the actual change. The string is rendered prominent in
    /// the user interface.
    String label{};

    /// A flag which indicates that user confirmation is needed before applying the change.
    Optional<Boolean> needs_confirmation;

    /// A human-readable string which is rendered less prominent in the user interface.
    Optional<String> description;
};

/// A workspace edit represents changes to many resources managed in the workspace. The edit should
/// either provide `changes` or `documentChanges`. If documentChanges are present they are preferred
/// over `changes` if the client can handle versioned document edits. Since version 3.13.0 a
/// workspace edit can contain resource operations as well. If resource operations are present
/// clients need to execute the operations in the order in which they are provided. So a workspace
/// edit for example can consist of the following two changes: (1) a create file a.txt and (2) a
/// text document edit which insert text into file a.txt. An invalid sequence (e.g. (1) delete file
/// a.txt and (2) insert text into file a.txt) will cause failure of the operation. How the client
/// recovers from the failure is described by the client capability:
/// `workspace.workspaceEdit.failureHandling`
struct WorkspaceEdit {
    /// Holds changes to existing resources.
    Optional<std::unordered_map<DocumentUri, std::vector<lsp::TextEdit>>> changes;

    /// Depending on the client capability `workspace.workspaceEdit.resourceOperations` document
    /// changes are either an array of `TextDocumentEdit`s to express changes to n different text
    /// documents where each text document edit addresses a specific version of a text document. Or
    /// it can contain above `TextDocumentEdit`s mixed with create, rename and delete file / folder
    /// operations. Whether a client supports versioned document edits is expressed via
    /// `workspace.workspaceEdit.documentChanges` client capability. If a client neither supports
    /// `documentChanges` nor `workspace.workspaceEdit.resourceOperations` then only plain
    /// `TextEdit`s using the `changes` property are supported.
    Optional<std::vector<
        OneOf<lsp::TextDocumentEdit, lsp::CreateFile, lsp::RenameFile, lsp::DeleteFile>>>
        document_changes;

    /// A map of change annotations that can be referenced in `AnnotatedTextEdit`s or create, rename
    /// and delete file / folder operations. Whether clients honor this property depends on the
    /// client capability `workspace.changeAnnotationSupport`.
    ///
    /// @since 3.16.0
    Optional<std::unordered_map<lsp::ChangeAnnotationIdentifier, lsp::ChangeAnnotation>>
        change_annotations;
};

/// Matching options for the file operation pattern.
///
/// @since 3.16.0
struct FileOperationPatternOptions {
    /// The pattern should be matched ignoring casing.
    Optional<Boolean> ignore_case;
};

/// A pattern to describe in which file operation requests or notifications the server is interested
/// in receiving.
///
/// @since 3.16.0
struct FileOperationPattern {
    /// The glob pattern to match. Glob patterns can have the following syntax: - `*` to match one
    /// or more characters in a path segment - `?` to match on one character in a path segment -
    /// `**` to match any number of path segments, including none - `{}` to group sub patterns into
    /// an OR expression. (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files) -
    /// `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to
    /// match on `example.0`, `example.1`, …) - `[!...]` to negate a range of characters to match in
    /// a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not
    /// `example.0`)
    String glob{};

    /// Whether to match files or folders with this pattern. Matches both if undefined.
    Optional<lsp::FileOperationPatternKind> matches;

    /// Additional options used during matching.
    Optional<lsp::FileOperationPatternOptions> options;
};

/// A filter to describe in which file operation requests or notifications the server is interested
/// in receiving.
///
/// @since 3.16.0
struct FileOperationFilter {
    /// A Uri scheme like `file` or `untitled`.
    Optional<String> scheme;

    /// The actual file operation pattern.
    lsp::FileOperationPattern pattern{};
};

/// The options to register for file operations.
///
/// @since 3.16.0
struct FileOperationRegistrationOptions {
    /// The actual filters.
    std::vector<lsp::FileOperationFilter> filters{};
};

/// Represents information on a file/folder rename.
///
/// @since 3.16.0
struct FileRename {
    /// A file:// URI for the original location of the file/folder being renamed.
    String old_uri{};

    /// A file:// URI for the new location of the file/folder being renamed.
    String new_uri{};
};

/// The parameters sent in notifications/requests for user-initiated renames of files.
///
/// @since 3.16.0
struct RenameFilesParams {
    /// An array of all files/folders renamed in this operation. When a folder is renamed, only the
    /// folder will be included, and not its children.
    std::vector<lsp::FileRename> files{};
};

/// Represents information on a file/folder delete.
///
/// @since 3.16.0
struct FileDelete {
    /// A file:// URI for the location of the file/folder being deleted.
    String uri{};
};

/// The parameters sent in notifications/requests for user-initiated deletes of files.
///
/// @since 3.16.0
struct DeleteFilesParams {
    /// An array of all files/folders deleted in this operation.
    std::vector<lsp::FileDelete> files{};
};

/// No documentation available
struct MonikerParams : lsp::TextDocumentPositionParams {};

/// Moniker definition to match LSIF 0.5 moniker definition.
///
/// @since 3.16.0
struct Moniker {
    /// The scheme of the moniker. For example tsc or .Net
    String scheme{};

    /// The identifier of the moniker. The value is opaque in LSIF however schema owners are allowed
    /// to define the structure if they want.
    String identifier{};

    /// The scope in which the moniker is unique
    lsp::UniquenessLevel unique{};

    /// The moniker kind if known.
    Optional<lsp::MonikerKind> kind;
};

/// No documentation available
struct MonikerOptions {};

/// No documentation available
struct MonikerRegistrationOptions : lsp::TextDocumentRegistrationOptions, lsp::MonikerOptions {};

/// The parameter of a `textDocument/prepareTypeHierarchy` request.
///
/// @since 3.17.0
struct TypeHierarchyPrepareParams : lsp::TextDocumentPositionParams {};

/// @since 3.17.0
struct TypeHierarchyItem {
    /// The name of this item.
    String name{};

    /// The kind of this item.
    lsp::SymbolKind kind{};

    /// Tags for this item.
    Optional<std::vector<lsp::SymbolTag>> tags;

    /// More detail for this item, e.g. the signature of a function.
    Optional<String> detail;

    /// The resource identifier of this item.
    DocumentUri uri{};

    /// The range enclosing this symbol not including leading/trailing whitespace but everything
    /// else, e.g. comments and code.
    lsp::Range range{};

    /// The range that should be selected and revealed when this symbol is being picked, e.g. the
    /// name of a function. Must be contained by the TypeHierarchyItem.range `range`.
    lsp::Range selection_range{};

    /// A data entry field that is preserved between a type hierarchy prepare and supertypes or
    /// subtypes requests. It could also be used to identify the type hierarchy in the server,
    /// helping improve the performance on resolving supertypes and subtypes.
    Optional<lsp::LSPAny> data;
};

/// Type hierarchy options used during static registration.
///
/// @since 3.17.0
struct TypeHierarchyOptions {};

/// Type hierarchy options used during static or dynamic registration.
///
/// @since 3.17.0
struct TypeHierarchyRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                          lsp::TypeHierarchyOptions {};

/// The parameter of a `typeHierarchy/supertypes` request.
///
/// @since 3.17.0
struct TypeHierarchySupertypesParams {
    /// No documentation available
    lsp::TypeHierarchyItem item{};
};

/// The parameter of a `typeHierarchy/subtypes` request.
///
/// @since 3.17.0
struct TypeHierarchySubtypesParams {
    /// No documentation available
    lsp::TypeHierarchyItem item{};
};

/// @since 3.17.0
struct InlineValueContext {
    /// The stack frame (as a DAP Id) where the execution has stopped.
    Integer frame_id{};

    /// The document range where execution has stopped. Typically the end position of the range
    /// denotes the line where the inline values are shown.
    lsp::Range stopped_location{};
};

/// A parameter literal used in inline value requests.
///
/// @since 3.17.0
struct InlineValueParams {
    /// The text document.
    lsp::TextDocumentIdentifier text_document{};

    /// The document range for which inline values should be computed.
    lsp::Range range{};

    /// Additional information about the context in which inline values were requested.
    lsp::InlineValueContext context{};
};

/// Inline value options used during static registration.
///
/// @since 3.17.0
struct InlineValueOptions {};

/// Inline value options used during static or dynamic registration.
///
/// @since 3.17.0
struct InlineValueRegistrationOptions : lsp::InlineValueOptions,
                                        lsp::TextDocumentRegistrationOptions {};

/// A parameter literal used in inlay hint requests.
///
/// @since 3.17.0
struct InlayHintParams {
    /// The text document.
    lsp::TextDocumentIdentifier text_document{};

    /// The document range for which inlay hints should be computed.
    lsp::Range range{};
};

/// A `MarkupContent` literal represents a string value which content is interpreted base on its
/// kind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds. If the
/// kind is `markdown` then the value can contain fenced code blocks like in GitHub issues. See
/// https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting Here
/// is an example how such a string can be constructed using JavaScript / TypeScript: ```ts let
/// markdown: MarkdownContent = { kind: MarkupKind.Markdown, value: [  '# Header',  'Some text',
/// '```typescript',  'someCode();',  '```' ].join('\n') }; ``` *Please Note* that clients might
/// sanitize the return markdown. A client could decide to remove HTML from the markdown to avoid
/// script execution.
struct MarkupContent {
    /// The type of the Markup
    lsp::MarkupKind kind{};

    /// The content itself
    String value{};
};

/// Represents a reference to a command. Provides a title which will be used to represent a command
/// in the UI and, optionally, an array of arguments which will be passed to the command handler
/// function when invoked.
struct Command {
    /// Title of the command, like `save`.
    String title{};

    /// The identifier of the actual command handler.
    String command{};

    /// Arguments that the command handler should be invoked with.
    Optional<std::vector<lsp::LSPAny>> arguments;
};

/// An inlay hint label part allows for interactive and composite labels of inlay hints.
///
/// @since 3.17.0
struct InlayHintLabelPart {
    /// The value of this label part.
    String value{};

    /// The tooltip text when you hover over this label part. Depending on the client capability
    /// `inlayHint.resolveSupport` clients might resolve this property late using the resolve
    /// request.
    Optional<OneOf<String, lsp::MarkupContent>> tooltip;

    /// An optional source code location that represents this label part. The editor will use this
    /// location for the hover and for code navigation features: This part will become a clickable
    /// link that resolves to the definition of the symbol at the given location (not necessarily
    /// the location itself), it shows the hover that shows at the given location, and it shows a
    /// context menu with further code navigation commands. Depending on the client capability
    /// `inlayHint.resolveSupport` clients might resolve this property late using the resolve
    /// request.
    Optional<lsp::Location> location;

    /// An optional command for this label part. Depending on the client capability
    /// `inlayHint.resolveSupport` clients might resolve this property late using the resolve
    /// request.
    Optional<lsp::Command> command;
};

/// Inlay hint information.
///
/// @since 3.17.0
struct InlayHint {
    /// The position of this hint.
    lsp::Position position{};

    /// The label of this hint. A human readable string or an array of InlayHintLabelPart label
    /// parts. *Note* that neither the string nor the label part can be empty.
    OneOf<String, std::vector<lsp::InlayHintLabelPart>> label{};

    /// The kind of this hint. Can be omitted in which case the client should fall back to a
    /// reasonable default.
    Optional<lsp::InlayHintKind> kind;

    /// Optional text edits that are performed when accepting this inlay hint. *Note* that edits are
    /// expected to change the document so that the inlay hint (or its nearest variant) is now part
    /// of the document and the inlay hint itself is now obsolete.
    Optional<std::vector<lsp::TextEdit>> text_edits;

    /// The tooltip text when you hover over this item.
    Optional<OneOf<String, lsp::MarkupContent>> tooltip;

    /// Render padding before the hint. Note: Padding should use the editor's background color, not
    /// the background color of the hint itself. That means padding can be used to visually
    /// align/separate an inlay hint.
    Optional<Boolean> padding_left;

    /// Render padding after the hint. Note: Padding should use the editor's background color, not
    /// the background color of the hint itself. That means padding can be used to visually
    /// align/separate an inlay hint.
    Optional<Boolean> padding_right;

    /// A data entry field that is preserved on an inlay hint between a `textDocument/inlayHint` and
    /// a `inlayHint/resolve` request.
    Optional<lsp::LSPAny> data;
};

/// Inlay hint options used during static registration.
///
/// @since 3.17.0
struct InlayHintOptions {
    /// The server provides support to resolve additional information for an inlay hint item.
    Optional<Boolean> resolve_provider;
};

/// Inlay hint options used during static or dynamic registration.
///
/// @since 3.17.0
struct InlayHintRegistrationOptions : lsp::InlayHintOptions,
                                      lsp::TextDocumentRegistrationOptions {};

/// Parameters of the document diagnostic request.
///
/// @since 3.17.0
struct DocumentDiagnosticParams {
    /// The text document.
    lsp::TextDocumentIdentifier text_document{};

    /// The additional identifier provided during registration.
    Optional<String> identifier;

    /// The result id of a previous response if provided.
    Optional<String> previous_result_id;
};

/// A diagnostic report indicating that the last returned report is still accurate.
///
/// @since 3.17.0
struct UnchangedDocumentDiagnosticReport {
    /// The structure type identifier
    static constexpr std::string_view kKind = "unchanged";

    /// A result id which will be sent on the next diagnostic request for the same document.
    String result_id{};
};

/// Structure to capture a description for an error code.
///
/// @since 3.16.0
struct CodeDescription {
    /// An URI to open with more information about the diagnostic error.
    Uri href{};
};

/// Represents a related message and source code location for a diagnostic. This should be used to
/// point to code locations that cause or related to a diagnostics, e.g when duplicating a symbol in
/// a scope.
struct DiagnosticRelatedInformation {
    /// The location of this related diagnostic information.
    lsp::Location location{};

    /// The message of this related diagnostic information.
    String message{};
};

/// Represents a diagnostic, such as a compiler error or warning. Diagnostic objects are only valid
/// in the scope of a resource.
struct Diagnostic {
    /// The range at which the message applies
    lsp::Range range{};

    /// The diagnostic's severity. Can be omitted. If omitted it is up to the client to interpret
    /// diagnostics as error, warning, info or hint.
    Optional<lsp::DiagnosticSeverity> severity;

    /// The diagnostic's code, which usually appear in the user interface.
    Optional<OneOf<Integer, String>> code;

    /// An optional property to describe the error code. Requires the code field (above) to be
    /// present/not null.
    ///
    /// @since 3.16.0
    Optional<lsp::CodeDescription> code_description;

    /// A human-readable string describing the source of this diagnostic, e.g. 'typescript' or
    /// 'super lint'. It usually appears in the user interface.
    Optional<String> source;

    /// The diagnostic's message. It usually appears in the user interface
    String message{};

    /// Additional metadata about the diagnostic.
    ///
    /// @since 3.15.0
    Optional<std::vector<lsp::DiagnosticTag>> tags;

    /// An array of related diagnostic information, e.g. when symbol-names within a scope collide
    /// all definitions can be marked via this property.
    Optional<std::vector<lsp::DiagnosticRelatedInformation>> related_information;

    /// A data entry field that is preserved between a `textDocument/publishDiagnostics`
    /// notification and `textDocument/codeAction` request.
    ///
    /// @since 3.16.0
    Optional<lsp::LSPAny> data;
};

/// A diagnostic report with a full set of problems.
///
/// @since 3.17.0
struct FullDocumentDiagnosticReport {
    /// The structure type identifier
    static constexpr std::string_view kKind = "full";

    /// An optional result id. If provided it will be sent on the next diagnostic request for the
    /// same document.
    Optional<String> result_id;

    /// The actual items.
    std::vector<lsp::Diagnostic> items{};
};

/// A partial result for a document diagnostic report.
///
/// @since 3.17.0
struct DocumentDiagnosticReportPartialResult {
    /// No documentation available
    std::unordered_map<
        DocumentUri,
        OneOf<lsp::FullDocumentDiagnosticReport, lsp::UnchangedDocumentDiagnosticReport>>
        related_documents{};
};

/// Cancellation data returned from a diagnostic request.
///
/// @since 3.17.0
struct DiagnosticServerCancellationData {
    /// No documentation available
    Boolean retrigger_request{};
};

/// Diagnostic options.
///
/// @since 3.17.0
struct DiagnosticOptions {
    /// An optional identifier under which the diagnostics are managed by the client.
    Optional<String> identifier;

    /// Whether the language has inter file dependencies meaning that editing code in one file can
    /// result in a different diagnostic set in another file. Inter file dependencies are common for
    /// most programming languages and typically uncommon for linters.
    Boolean inter_file_dependencies{};

    /// The server provides support for workspace diagnostics as well.
    Boolean workspace_diagnostics{};
};

/// Diagnostic registration options.
///
/// @since 3.17.0
struct DiagnosticRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                       lsp::DiagnosticOptions {};

/// A previous result id in a workspace pull request.
///
/// @since 3.17.0
struct PreviousResultId {
    /// The URI for which the client knowns a result id.
    DocumentUri uri{};

    /// The value of the previous result id.
    String value{};
};

/// Parameters of the workspace diagnostic request.
///
/// @since 3.17.0
struct WorkspaceDiagnosticParams {
    /// The additional identifier provided during registration.
    Optional<String> identifier;

    /// The currently known diagnostic reports with their previous result ids.
    std::vector<lsp::PreviousResultId> previous_result_ids{};
};

/// A workspace diagnostic report.
///
/// @since 3.17.0
struct WorkspaceDiagnosticReport {
    /// No documentation available
    std::vector<lsp::WorkspaceDocumentDiagnosticReport> items{};
};

/// A partial result for a workspace diagnostic report.
///
/// @since 3.17.0
struct WorkspaceDiagnosticReportPartialResult {
    /// No documentation available
    std::vector<lsp::WorkspaceDocumentDiagnosticReport> items{};
};

/// No documentation available
struct ExecutionSummary {
    /// A strict monotonically increasing value indicating the execution order of a cell inside a
    /// notebook.
    Uinteger execution_order{};

    /// Whether the execution was successful or not if known by the client.
    Optional<Boolean> success;
};

/// A notebook cell. A cell's document URI must be unique across ALL notebook cells and can
/// therefore be used to uniquely identify a notebook cell or the cell's text document.
///
/// @since 3.17.0
struct NotebookCell {
    /// The cell's kind
    lsp::NotebookCellKind kind{};

    /// The URI of the cell's text document content.
    DocumentUri document{};

    /// Additional metadata stored with the cell. Note: should always be an object literal (e.g.
    /// LSPObject)
    Optional<lsp::LSPObject> metadata;

    /// Additional execution summary information if supported by the client.
    Optional<lsp::ExecutionSummary> execution_summary;
};

/// A notebook document.
///
/// @since 3.17.0
struct NotebookDocument {
    /// The notebook document's uri.
    Uri uri{};

    /// The type of the notebook.
    String notebook_type{};

    /// The version number of this document (it will increase after each change, including
    /// undo/redo).
    Integer version{};

    /// Additional metadata stored with the notebook document. Note: should always be an object
    /// literal (e.g. LSPObject)
    Optional<lsp::LSPObject> metadata;

    /// The cells of a notebook.
    std::vector<lsp::NotebookCell> cells{};
};

/// An item to transfer a text document from the client to the server.
struct TextDocumentItem {
    /// The text document's uri.
    DocumentUri uri{};

    /// The text document's language identifier.
    String language_id{};

    /// The version number of this document (it will increase after each change, including
    /// undo/redo).
    Integer version{};

    /// The content of the opened text document.
    String text{};
};

/// The params sent in an open notebook document notification.
///
/// @since 3.17.0
struct DidOpenNotebookDocumentParams {
    /// The notebook document that got opened.
    lsp::NotebookDocument notebook_document{};

    /// The text documents that represent the content of a notebook cell.
    std::vector<lsp::TextDocumentItem> cell_text_documents{};
};

/// A versioned notebook document identifier.
///
/// @since 3.17.0
struct VersionedNotebookDocumentIdentifier {
    /// The version number of this notebook document.
    Integer version{};

    /// The notebook document's uri.
    Uri uri{};
};

/// A change describing how to move a `NotebookCell` array from state S to S'.
///
/// @since 3.17.0
struct NotebookCellArrayChange {
    /// The start oftest of the cell that changed.
    Uinteger start{};

    /// The deleted cells
    Uinteger delete_count{};

    /// The new cells, if any
    Optional<std::vector<lsp::NotebookCell>> cells;
};

/// Structural changes to cells in a notebook document.
///
/// @since 3.18.0
///
/// Proposed in:
struct NotebookDocumentCellChangeStructure {
    /// The change to the cell array.
    lsp::NotebookCellArrayChange array{};

    /// Additional opened cell text documents.
    Optional<std::vector<lsp::TextDocumentItem>> did_open;

    /// Additional closed cell text documents.
    Optional<std::vector<lsp::TextDocumentIdentifier>> did_close;
};

/// A text document identifier to denote a specific version of a text document.
struct VersionedTextDocumentIdentifier : lsp::TextDocumentIdentifier {
    /// The version number of this document.
    Integer version{};
};

/// Content changes to a cell in a notebook document.
///
/// @since 3.18.0
///
/// Proposed in:
struct NotebookDocumentCellContentChanges {
    /// No documentation available
    lsp::VersionedTextDocumentIdentifier document{};

    /// No documentation available
    std::vector<lsp::TextDocumentContentChangeEvent> changes{};
};

/// Cell changes to a notebook document.
///
/// @since 3.18.0
///
/// Proposed in:
struct NotebookDocumentCellChanges {
    /// Changes to the cell structure to add or remove cells.
    Optional<lsp::NotebookDocumentCellChangeStructure> structure;

    /// Changes to notebook cells properties like its kind, execution summary or metadata.
    Optional<std::vector<lsp::NotebookCell>> data;

    /// Changes to the text content of notebook cells.
    Optional<std::vector<lsp::NotebookDocumentCellContentChanges>> text_content;
};

/// A change event for a notebook document.
///
/// @since 3.17.0
struct NotebookDocumentChangeEvent {
    /// The changed meta data if any. Note: should always be an object literal (e.g. LSPObject)
    Optional<lsp::LSPObject> metadata;

    /// Changes to cells
    Optional<lsp::NotebookDocumentCellChanges> cells;
};

/// The params sent in a change notebook document notification.
///
/// @since 3.17.0
struct DidChangeNotebookDocumentParams {
    /// The notebook document that did change. The version number points to the version after all
    /// provided changes have been applied. If only the text document content of a cell changes the
    /// notebook version doesn't necessarily have to change.
    lsp::VersionedNotebookDocumentIdentifier notebook_document{};

    /// The actual changes to the notebook document. The changes describe single state changes to
    /// the notebook document. So if there are two changes c1 (at array index 0) and c2 (at array
    /// index 1) for a notebook in state S then c1 moves the notebook from S to S' and c2 from S' to
    /// S''. So c1 is computed on the state S and c2 is computed on the state S'. To mirror the
    /// content of a notebook using change events use the following approach: - start with the same
    /// initial content - apply the 'notebookDocument/didChange' notifications in the order you
    /// receive them. - apply the `NotebookChangeEvent`s in a single notification in the order  you
    /// receive them.
    lsp::NotebookDocumentChangeEvent change{};
};

/// A literal to identify a notebook document in the client.
///
/// @since 3.17.0
struct NotebookDocumentIdentifier {
    /// The notebook document's uri.
    Uri uri{};
};

/// The params sent in a save notebook document notification.
///
/// @since 3.17.0
struct DidSaveNotebookDocumentParams {
    /// The notebook document that got saved.
    lsp::NotebookDocumentIdentifier notebook_document{};
};

/// The params sent in a close notebook document notification.
///
/// @since 3.17.0
struct DidCloseNotebookDocumentParams {
    /// The notebook document that got closed.
    lsp::NotebookDocumentIdentifier notebook_document{};

    /// The text documents that represent the content of a notebook cell that got closed.
    std::vector<lsp::TextDocumentIdentifier> cell_text_documents{};
};

/// Describes the currently selected completion item.
///
/// @since 3.18.0
///
/// Proposed in:
struct SelectedCompletionInfo {
    /// The range that will be replaced if this completion item is accepted.
    lsp::Range range{};

    /// The text the range will be replaced with if this completion is accepted.
    String text{};
};

/// Provides information about the context in which an inline completion was requested.
///
/// @since 3.18.0
///
/// Proposed in:
struct InlineCompletionContext {
    /// Describes how the inline completion was triggered.
    lsp::InlineCompletionTriggerKind trigger_kind{};

    /// Provides information about the currently selected item in the autocomplete widget if it is
    /// visible.
    Optional<lsp::SelectedCompletionInfo> selected_completion_info;
};

/// A parameter literal used in inline completion requests.
///
/// @since 3.18.0
///
/// Proposed in:
struct InlineCompletionParams : lsp::TextDocumentPositionParams {
    /// Additional information about the context in which inline completions were requested.
    lsp::InlineCompletionContext context{};
};

/// A string value used as a snippet is a template which allows to insert text and to control the
/// editor cursor when insertion happens. A snippet can define tab stops and placeholders with `$1`,
/// `$2` and `${3:foo}`. `$0` defines the final tab stop, it defaults to the end of the snippet.
/// Variables are defined with `$name` and `${name:default value}`.
///
/// @since 3.18.0
///
/// Proposed in:
struct StringValue {
    /// The structure type identifier
    static constexpr std::string_view kKind = "snippet";

    /// The snippet string.
    String value{};
};

/// An inline completion item represents a text snippet that is proposed inline to complete text
/// that is being typed.
///
/// @since 3.18.0
///
/// Proposed in:
struct InlineCompletionItem {
    /// The text to replace the range with. Must be set.
    OneOf<String, lsp::StringValue> insert_text{};

    /// A text that is used to decide if this inline completion should be shown. When `falsy` the
    /// InlineCompletionItem.insertText is used.
    Optional<String> filter_text;

    /// The range to replace. Must begin and end on the same line.
    Optional<lsp::Range> range;

    /// An optional Command that is executed *after* inserting this completion.
    Optional<lsp::Command> command;
};

/// Represents a collection of InlineCompletionItem inline completion items to be presented in the
/// editor.
///
/// @since 3.18.0
///
/// Proposed in:
struct InlineCompletionList {
    /// The inline completion items
    std::vector<lsp::InlineCompletionItem> items{};
};

/// Inline completion options used during static registration.
///
/// @since 3.18.0
///
/// Proposed in:
struct InlineCompletionOptions {};

/// Inline completion options used during static or dynamic registration.
///
/// @since 3.18.0
///
/// Proposed in:
struct InlineCompletionRegistrationOptions : lsp::InlineCompletionOptions,
                                             lsp::TextDocumentRegistrationOptions {};

/// General parameters to register for a notification or to register a provider.
struct Registration {
    /// The id used to register the request. The id can be used to deregister the request again.
    String id{};

    /// The method / capability to register for.
    String method{};

    /// Options necessary for the registration.
    Optional<lsp::LSPAny> register_options;
};

/// No documentation available
struct RegistrationParams {
    /// No documentation available
    std::vector<lsp::Registration> registrations{};
};

/// General parameters to unregister a request or notification.
struct Unregistration {
    /// The id used to unregister the request or notification. Usually an id provided during the
    /// register request.
    String id{};

    /// The method to unregister for.
    String method{};
};

/// No documentation available
struct UnregistrationParams {
    /// No documentation available
    std::vector<lsp::Unregistration> unregisterations{};
};

/// Information about the client
///
/// @since 3.15.0
///
/// @since 3.18.0 ClientInfo type name added.
///
/// Proposed in:
struct ClientInfo {
    /// The name of the client as defined by the client.
    String name{};

    /// The client's version as defined by the client.
    Optional<String> version;
};

/// @since 3.18.0
///
/// Proposed in:
struct ChangeAnnotationsSupportOptions {
    /// Whether the client groups edits with equal labels into tree nodes, for instance all edits
    /// labelled with "Changes in Strings" would be a tree node.
    Optional<Boolean> groups_on_label;
};

/// No documentation available
struct WorkspaceEditClientCapabilities {
    /// The client supports versioned document changes in `WorkspaceEdit`s
    Optional<Boolean> document_changes;

    /// The resource operations the client supports. Clients should at least support 'create',
    /// 'rename' and 'delete' files and folders.
    ///
    /// @since 3.13.0
    Optional<std::vector<lsp::ResourceOperationKind>> resource_operations;

    /// The failure handling strategy of a client if applying the workspace edit fails.
    ///
    /// @since 3.13.0
    Optional<lsp::FailureHandlingKind> failure_handling;

    /// Whether the client normalizes line endings to the client specific setting. If set to `true`
    /// the client will normalize line ending characters in a workspace edit to the client-specified
    /// new line character.
    ///
    /// @since 3.16.0
    Optional<Boolean> normalizes_line_endings;

    /// Whether the client in general supports change annotations on text edits, create file, rename
    /// file and delete file changes.
    ///
    /// @since 3.16.0
    Optional<lsp::ChangeAnnotationsSupportOptions> change_annotation_support;
};

/// No documentation available
struct DidChangeConfigurationClientCapabilities {
    /// Did change configuration notification supports dynamic registration.
    Optional<Boolean> dynamic_registration;
};

/// No documentation available
struct DidChangeWatchedFilesClientCapabilities {
    /// Did change watched files notification supports dynamic registration. Please note that the
    /// current protocol doesn't support static configuration for file changes from the server side.
    Optional<Boolean> dynamic_registration;

    /// Whether the client has support for RelativePattern relative pattern or not.
    ///
    /// @since 3.17.0
    Optional<Boolean> relative_pattern_support;
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientSymbolKindOptions {
    /// The symbol kind values the client supports. When this property exists the client also
    /// guarantees that it will handle values outside its set gracefully and falls back to a default
    /// value when unknown. If this property is not present the client only supports the symbol
    /// kinds from `File` to `Array` as defined in the initial version of the protocol.
    Optional<std::vector<lsp::SymbolKind>> value_set;
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientSymbolTagOptions {
    /// The tags supported by the client.
    std::vector<lsp::SymbolTag> value_set{};
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientSymbolResolveOptions {
    /// The properties that a client can resolve lazily. Usually `location.range`
    std::vector<String> properties{};
};

/// Client capabilities for a WorkspaceSymbolRequest.
struct WorkspaceSymbolClientCapabilities {
    /// Symbol request supports dynamic registration.
    Optional<Boolean> dynamic_registration;

    /// Specific capabilities for the `SymbolKind` in the `workspace/symbol` request.
    Optional<lsp::ClientSymbolKindOptions> symbol_kind;

    /// The client supports tags on `SymbolInformation`. Clients supporting tags have to handle
    /// unknown tags gracefully.
    ///
    /// @since 3.16.0
    Optional<lsp::ClientSymbolTagOptions> tag_support;

    /// The client support partial workspace symbols. The client will send the request
    /// `workspaceSymbol/resolve` to the server to resolve additional properties.
    ///
    /// @since 3.17.0
    Optional<lsp::ClientSymbolResolveOptions> resolve_support;
};

/// The client capabilities of a ExecuteCommandRequest.
struct ExecuteCommandClientCapabilities {
    /// Execute command supports dynamic registration.
    Optional<Boolean> dynamic_registration;
};

/// @since 3.16.0
struct SemanticTokensWorkspaceClientCapabilities {
    /// Whether the client implementation supports a refresh request sent from the server to the
    /// client. Note that this event is global and will force the client to refresh all semantic
    /// tokens currently shown. It should be used with absolute care and is useful for situation
    /// where a server for example detects a project wide change that requires such a calculation.
    Optional<Boolean> refresh_support;
};

/// @since 3.16.0
struct CodeLensWorkspaceClientCapabilities {
    /// Whether the client implementation supports a refresh request sent from the server to the
    /// client. Note that this event is global and will force the client to refresh all code lenses
    /// currently shown. It should be used with absolute care and is useful for situation where a
    /// server for example detect a project wide change that requires such a calculation.
    Optional<Boolean> refresh_support;
};

/// Capabilities relating to events from file operations by the user in the client. These events do
/// not come from the file system, they come from user operations like renaming a file in the UI.
///
/// @since 3.16.0
struct FileOperationClientCapabilities {
    /// Whether the client supports dynamic registration for file requests/notifications.
    Optional<Boolean> dynamic_registration;

    /// The client has support for sending didCreateFiles notifications.
    Optional<Boolean> did_create;

    /// The client has support for sending willCreateFiles requests.
    Optional<Boolean> will_create;

    /// The client has support for sending didRenameFiles notifications.
    Optional<Boolean> did_rename;

    /// The client has support for sending willRenameFiles requests.
    Optional<Boolean> will_rename;

    /// The client has support for sending didDeleteFiles notifications.
    Optional<Boolean> did_delete;

    /// The client has support for sending willDeleteFiles requests.
    Optional<Boolean> will_delete;
};

/// Client workspace capabilities specific to inline values.
///
/// @since 3.17.0
struct InlineValueWorkspaceClientCapabilities {
    /// Whether the client implementation supports a refresh request sent from the server to the
    /// client. Note that this event is global and will force the client to refresh all inline
    /// values currently shown. It should be used with absolute care and is useful for situation
    /// where a server for example detects a project wide change that requires such a calculation.
    Optional<Boolean> refresh_support;
};

/// Client workspace capabilities specific to inlay hints.
///
/// @since 3.17.0
struct InlayHintWorkspaceClientCapabilities {
    /// Whether the client implementation supports a refresh request sent from the server to the
    /// client. Note that this event is global and will force the client to refresh all inlay hints
    /// currently shown. It should be used with absolute care and is useful for situation where a
    /// server for example detects a project wide change that requires such a calculation.
    Optional<Boolean> refresh_support;
};

/// Workspace client capabilities specific to diagnostic pull requests.
///
/// @since 3.17.0
struct DiagnosticWorkspaceClientCapabilities {
    /// Whether the client implementation supports a refresh request sent from the server to the
    /// client. Note that this event is global and will force the client to refresh all pulled
    /// diagnostics currently shown. It should be used with absolute care and is useful for
    /// situation where a server for example detects a project wide change that requires such a
    /// calculation.
    Optional<Boolean> refresh_support;
};

/// Client workspace capabilities specific to folding ranges
///
/// @since 3.18.0
///
/// Proposed in:
struct FoldingRangeWorkspaceClientCapabilities {
    /// Whether the client implementation supports a refresh request sent from the server to the
    /// client. Note that this event is global and will force the client to refresh all folding
    /// ranges currently shown. It should be used with absolute care and is useful for situation
    /// where a server for example detects a project wide change that requires such a calculation.
    ///
    /// @since 3.18.0
    ///
    /// Proposed in:
    Optional<Boolean> refresh_support;
};

/// Workspace specific client capabilities.
struct WorkspaceClientCapabilities {
    /// The client supports applying batch edits to the workspace by supporting the request
    /// 'workspace/applyEdit'
    Optional<Boolean> apply_edit;

    /// Capabilities specific to `WorkspaceEdit`s.
    Optional<lsp::WorkspaceEditClientCapabilities> workspace_edit;

    /// Capabilities specific to the `workspace/didChangeConfiguration` notification.
    Optional<lsp::DidChangeConfigurationClientCapabilities> did_change_configuration;

    /// Capabilities specific to the `workspace/didChangeWatchedFiles` notification.
    Optional<lsp::DidChangeWatchedFilesClientCapabilities> did_change_watched_files;

    /// Capabilities specific to the `workspace/symbol` request.
    Optional<lsp::WorkspaceSymbolClientCapabilities> symbol;

    /// Capabilities specific to the `workspace/executeCommand` request.
    Optional<lsp::ExecuteCommandClientCapabilities> execute_command;

    /// The client has support for workspace folders.
    ///
    /// @since 3.6.0
    Optional<Boolean> workspace_folders;

    /// The client supports `workspace/configuration` requests.
    ///
    /// @since 3.6.0
    Optional<Boolean> configuration;

    /// Capabilities specific to the semantic token requests scoped to the workspace.
    ///
    /// @since 3.16.0.
    Optional<lsp::SemanticTokensWorkspaceClientCapabilities> semantic_tokens;

    /// Capabilities specific to the code lens requests scoped to the workspace.
    ///
    /// @since 3.16.0.
    Optional<lsp::CodeLensWorkspaceClientCapabilities> code_lens;

    /// The client has support for file notifications/requests for user operations on files.
    /// Since 3.16.0
    Optional<lsp::FileOperationClientCapabilities> file_operations;

    /// Capabilities specific to the inline values requests scoped to the workspace.
    ///
    /// @since 3.17.0.
    Optional<lsp::InlineValueWorkspaceClientCapabilities> inline_value;

    /// Capabilities specific to the inlay hint requests scoped to the workspace.
    ///
    /// @since 3.17.0.
    Optional<lsp::InlayHintWorkspaceClientCapabilities> inlay_hint;

    /// Capabilities specific to the diagnostic requests scoped to the workspace.
    ///
    /// @since 3.17.0.
    Optional<lsp::DiagnosticWorkspaceClientCapabilities> diagnostics;

    /// Capabilities specific to the folding range requests scoped to the workspace.
    ///
    /// @since 3.18.0
    ///
    /// Proposed in:
    Optional<lsp::FoldingRangeWorkspaceClientCapabilities> folding_range;
};

/// No documentation available
struct TextDocumentSyncClientCapabilities {
    /// Whether text document synchronization supports dynamic registration.
    Optional<Boolean> dynamic_registration;

    /// The client supports sending will save notifications.
    Optional<Boolean> will_save;

    /// The client supports sending a will save request and waits for a response providing text
    /// edits which will be applied to the document before it is saved.
    Optional<Boolean> will_save_wait_until;

    /// The client supports did save notifications.
    Optional<Boolean> did_save;
};

/// @since 3.18.0
///
/// Proposed in:
struct CompletionItemTagOptions {
    /// The tags supported by the client.
    std::vector<lsp::CompletionItemTag> value_set{};
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientCompletionItemResolveOptions {
    /// The properties that a client can resolve lazily.
    std::vector<String> properties{};
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientCompletionItemInsertTextModeOptions {
    /// No documentation available
    std::vector<lsp::InsertTextMode> value_set{};
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientCompletionItemOptions {
    /// Client supports snippets as insert text. A snippet can define tab stops and placeholders
    /// with `$1`, `$2` and `${3:foo}`. `$0` defines the final tab stop, it defaults to the end of
    /// the snippet. Placeholders with equal identifiers are linked, that is typing in one will
    /// update others too.
    Optional<Boolean> snippet_support;

    /// Client supports commit characters on a completion item.
    Optional<Boolean> commit_characters_support;

    /// Client supports the following content formats for the documentation property. The order
    /// describes the preferred format of the client.
    Optional<std::vector<lsp::MarkupKind>> documentation_format;

    /// Client supports the deprecated property on a completion item.
    Optional<Boolean> deprecated_support;

    /// Client supports the preselect property on a completion item.
    Optional<Boolean> preselect_support;

    /// Client supports the tag property on a completion item. Clients supporting tags have to
    /// handle unknown tags gracefully. Clients especially need to preserve unknown tags when
    /// sending a completion item back to the server in a resolve call.
    ///
    /// @since 3.15.0
    Optional<lsp::CompletionItemTagOptions> tag_support;

    /// Client support insert replace edit to control different behavior if a completion item is
    /// inserted in the text or should replace text.
    ///
    /// @since 3.16.0
    Optional<Boolean> insert_replace_support;

    /// Indicates which properties a client can resolve lazily on a completion item. Before
    /// version 3.16.0 only the predefined properties `documentation` and `details` could be
    /// resolved lazily.
    ///
    /// @since 3.16.0
    Optional<lsp::ClientCompletionItemResolveOptions> resolve_support;

    /// The client supports the `insertTextMode` property on a completion item to override the
    /// whitespace handling mode as defined by the client (see `insertTextMode`).
    ///
    /// @since 3.16.0
    Optional<lsp::ClientCompletionItemInsertTextModeOptions> insert_text_mode_support;

    /// The client has support for completion item label details (see also
    /// `CompletionItemLabelDetails`).
    ///
    /// @since 3.17.0
    Optional<Boolean> label_details_support;
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientCompletionItemOptionsKind {
    /// The completion item kind values the client supports. When this property exists the client
    /// also guarantees that it will handle values outside its set gracefully and falls back to a
    /// default value when unknown. If this property is not present the client only supports the
    /// completion items kinds from `Text` to `Reference` as defined in the initial version of the
    /// protocol.
    Optional<std::vector<lsp::CompletionItemKind>> value_set;
};

/// The client supports the following `CompletionList` specific capabilities.
///
/// @since 3.17.0
struct CompletionListCapabilities {
    /// The client supports the following itemDefaults on a completion list. The value lists the
    /// supported property names of the `CompletionList.itemDefaults` object. If omitted no
    /// properties are supported.
    ///
    /// @since 3.17.0
    Optional<std::vector<String>> item_defaults;
};

/// Completion client capabilities
struct CompletionClientCapabilities {
    /// Whether completion supports dynamic registration.
    Optional<Boolean> dynamic_registration;

    /// The client supports the following `CompletionItem` specific capabilities.
    Optional<lsp::ClientCompletionItemOptions> completion_item;

    /// No documentation available
    Optional<lsp::ClientCompletionItemOptionsKind> completion_item_kind;

    /// Defines how the client handles whitespace and indentation when accepting a completion item
    /// that uses multi line text in either `insertText` or `textEdit`.
    ///
    /// @since 3.17.0
    Optional<lsp::InsertTextMode> insert_text_mode;

    /// The client supports to send additional context information for a `textDocument/completion`
    /// request.
    Optional<Boolean> context_support;

    /// The client supports the following `CompletionList` specific capabilities.
    ///
    /// @since 3.17.0
    Optional<lsp::CompletionListCapabilities> completion_list;
};

/// No documentation available
struct HoverClientCapabilities {
    /// Whether hover supports dynamic registration.
    Optional<Boolean> dynamic_registration;

    /// Client supports the following content formats for the content property. The order describes
    /// the preferred format of the client.
    Optional<std::vector<lsp::MarkupKind>> content_format;
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientSignatureParameterInformationOptions {
    /// The client supports processing label offsets instead of a simple label string.
    ///
    /// @since 3.14.0
    Optional<Boolean> label_offset_support;
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientSignatureInformationOptions {
    /// Client supports the following content formats for the documentation property. The order
    /// describes the preferred format of the client.
    Optional<std::vector<lsp::MarkupKind>> documentation_format;

    /// Client capabilities specific to parameter information.
    Optional<lsp::ClientSignatureParameterInformationOptions> parameter_information;

    /// The client supports the `activeParameter` property on `SignatureInformation` literal.
    ///
    /// @since 3.16.0
    Optional<Boolean> active_parameter_support;
};

/// Client Capabilities for a SignatureHelpRequest.
struct SignatureHelpClientCapabilities {
    /// Whether signature help supports dynamic registration.
    Optional<Boolean> dynamic_registration;

    /// The client supports the following `SignatureInformation` specific properties.
    Optional<lsp::ClientSignatureInformationOptions> signature_information;

    /// The client supports to send additional context information for a
    /// `textDocument/signatureHelp` request. A client that opts into contextSupport will also
    /// support the `retriggerCharacters` on `SignatureHelpOptions`.
    ///
    /// @since 3.15.0
    Optional<Boolean> context_support;
};

/// @since 3.14.0
struct DeclarationClientCapabilities {
    /// Whether declaration supports dynamic registration. If this is set to `true` the client
    /// supports the new `DeclarationRegistrationOptions` return value for the corresponding server
    /// capability as well.
    Optional<Boolean> dynamic_registration;

    /// The client supports additional metadata in the form of declaration links.
    Optional<Boolean> link_support;
};

/// Client Capabilities for a DefinitionRequest.
struct DefinitionClientCapabilities {
    /// Whether definition supports dynamic registration.
    Optional<Boolean> dynamic_registration;

    /// The client supports additional metadata in the form of definition links.
    ///
    /// @since 3.14.0
    Optional<Boolean> link_support;
};

/// Since 3.6.0
struct TypeDefinitionClientCapabilities {
    /// Whether implementation supports dynamic registration. If this is set to `true` the client
    /// supports the new `TypeDefinitionRegistrationOptions` return value for the corresponding
    /// server capability as well.
    Optional<Boolean> dynamic_registration;

    /// The client supports additional metadata in the form of definition links. Since 3.14.0
    Optional<Boolean> link_support;
};

/// @since 3.6.0
struct ImplementationClientCapabilities {
    /// Whether implementation supports dynamic registration. If this is set to `true` the client
    /// supports the new `ImplementationRegistrationOptions` return value for the corresponding
    /// server capability as well.
    Optional<Boolean> dynamic_registration;

    /// The client supports additional metadata in the form of definition links.
    ///
    /// @since 3.14.0
    Optional<Boolean> link_support;
};

/// Client Capabilities for a ReferencesRequest.
struct ReferenceClientCapabilities {
    /// Whether references supports dynamic registration.
    Optional<Boolean> dynamic_registration;
};

/// Client Capabilities for a DocumentHighlightRequest.
struct DocumentHighlightClientCapabilities {
    /// Whether document highlight supports dynamic registration.
    Optional<Boolean> dynamic_registration;
};

/// Client Capabilities for a DocumentSymbolRequest.
struct DocumentSymbolClientCapabilities {
    /// Whether document symbol supports dynamic registration.
    Optional<Boolean> dynamic_registration;

    /// Specific capabilities for the `SymbolKind` in the `textDocument/documentSymbol` request.
    Optional<lsp::ClientSymbolKindOptions> symbol_kind;

    /// The client supports hierarchical document symbols.
    Optional<Boolean> hierarchical_document_symbol_support;

    /// The client supports tags on `SymbolInformation`. Tags are supported on `DocumentSymbol` if
    /// `hierarchicalDocumentSymbolSupport` is set to true. Clients supporting tags have to handle
    /// unknown tags gracefully.
    ///
    /// @since 3.16.0
    Optional<lsp::ClientSymbolTagOptions> tag_support;

    /// The client supports an additional label presented in the UI when registering a document
    /// symbol provider.
    ///
    /// @since 3.16.0
    Optional<Boolean> label_support;
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientCodeActionKindOptions {
    /// The code action kind values the client supports. When this property exists the client also
    /// guarantees that it will handle values outside its set gracefully and falls back to a default
    /// value when unknown.
    std::vector<lsp::CodeActionKind> value_set{};
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientCodeActionLiteralOptions {
    /// The code action kind is support with the following value set.
    lsp::ClientCodeActionKindOptions code_action_kind{};
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientCodeActionResolveOptions {
    /// The properties that a client can resolve lazily.
    std::vector<String> properties{};
};

/// The Client Capabilities of a CodeActionRequest.
struct CodeActionClientCapabilities {
    /// Whether code action supports dynamic registration.
    Optional<Boolean> dynamic_registration;

    /// The client support code action literals of type `CodeAction` as a valid response of the
    /// `textDocument/codeAction` request. If the property is not set the request can only return
    /// `Command` literals.
    ///
    /// @since 3.8.0
    Optional<lsp::ClientCodeActionLiteralOptions> code_action_literal_support;

    /// Whether code action supports the `isPreferred` property.
    ///
    /// @since 3.15.0
    Optional<Boolean> is_preferred_support;

    /// Whether code action supports the `disabled` property.
    ///
    /// @since 3.16.0
    Optional<Boolean> disabled_support;

    /// Whether code action supports the `data` property which is preserved between a
    /// `textDocument/codeAction` and a `codeAction/resolve` request.
    ///
    /// @since 3.16.0
    Optional<Boolean> data_support;

    /// Whether the client supports resolving additional code action properties via a separate
    /// `codeAction/resolve` request.
    ///
    /// @since 3.16.0
    Optional<lsp::ClientCodeActionResolveOptions> resolve_support;

    /// Whether the client honors the change annotations in text edits and resource operations
    /// returned via the `CodeAction#edit` property by for example presenting the workspace edit in
    /// the user interface and asking for confirmation.
    ///
    /// @since 3.16.0
    Optional<Boolean> honors_change_annotations;
};

/// The client capabilities of a CodeLensRequest.
struct CodeLensClientCapabilities {
    /// Whether code lens supports dynamic registration.
    Optional<Boolean> dynamic_registration;
};

/// The client capabilities of a DocumentLinkRequest.
struct DocumentLinkClientCapabilities {
    /// Whether document link supports dynamic registration.
    Optional<Boolean> dynamic_registration;

    /// Whether the client supports the `tooltip` property on `DocumentLink`.
    ///
    /// @since 3.15.0
    Optional<Boolean> tooltip_support;
};

/// No documentation available
struct DocumentColorClientCapabilities {
    /// Whether implementation supports dynamic registration. If this is set to `true` the client
    /// supports the new `DocumentColorRegistrationOptions` return value for the corresponding
    /// server capability as well.
    Optional<Boolean> dynamic_registration;
};

/// Client capabilities of a DocumentFormattingRequest.
struct DocumentFormattingClientCapabilities {
    /// Whether formatting supports dynamic registration.
    Optional<Boolean> dynamic_registration;
};

/// Client capabilities of a DocumentRangeFormattingRequest.
struct DocumentRangeFormattingClientCapabilities {
    /// Whether range formatting supports dynamic registration.
    Optional<Boolean> dynamic_registration;

    /// Whether the client supports formatting multiple ranges at once.
    ///
    /// @since 3.18.0
    ///
    /// Proposed in:
    Optional<Boolean> ranges_support;
};

/// Client capabilities of a DocumentOnTypeFormattingRequest.
struct DocumentOnTypeFormattingClientCapabilities {
    /// Whether on type formatting supports dynamic registration.
    Optional<Boolean> dynamic_registration;
};

/// No documentation available
struct RenameClientCapabilities {
    /// Whether rename supports dynamic registration.
    Optional<Boolean> dynamic_registration;

    /// Client supports testing for validity of rename operations before execution.
    ///
    /// @since 3.12.0
    Optional<Boolean> prepare_support;

    /// Client supports the default behavior result. The value indicates the default behavior used
    /// by the client.
    ///
    /// @since 3.16.0
    Optional<lsp::PrepareSupportDefaultBehavior> prepare_support_default_behavior;

    /// Whether the client honors the change annotations in text edits and resource operations
    /// returned via the rename request's workspace edit by for example presenting the workspace
    /// edit in the user interface and asking for confirmation.
    ///
    /// @since 3.16.0
    Optional<Boolean> honors_change_annotations;
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientFoldingRangeKindOptions {
    /// The folding range kind values the client supports. When this property exists the client also
    /// guarantees that it will handle values outside its set gracefully and falls back to a default
    /// value when unknown.
    Optional<std::vector<lsp::FoldingRangeKind>> value_set;
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientFoldingRangeOptions {
    /// If set, the client signals that it supports setting collapsedText on folding ranges to
    /// display custom labels instead of the default text.
    ///
    /// @since 3.17.0
    Optional<Boolean> collapsed_text;
};

/// No documentation available
struct FoldingRangeClientCapabilities {
    /// Whether implementation supports dynamic registration for folding range providers. If this is
    /// set to `true` the client supports the new `FoldingRangeRegistrationOptions` return value for
    /// the corresponding server capability as well.
    Optional<Boolean> dynamic_registration;

    /// The maximum number of folding ranges that the client prefers to receive per document. The
    /// value serves as a hint, servers are free to follow the limit.
    Optional<Uinteger> range_limit;

    /// If set, the client signals that it only supports folding complete lines. If set, client will
    /// ignore specified `startCharacter` and `endCharacter` properties in a FoldingRange.
    Optional<Boolean> line_folding_only;

    /// Specific options for the folding range kind.
    ///
    /// @since 3.17.0
    Optional<lsp::ClientFoldingRangeKindOptions> folding_range_kind;

    /// Specific options for the folding range.
    ///
    /// @since 3.17.0
    Optional<lsp::ClientFoldingRangeOptions> folding_range;
};

/// No documentation available
struct SelectionRangeClientCapabilities {
    /// Whether implementation supports dynamic registration for selection range providers. If this
    /// is set to `true` the client supports the new `SelectionRangeRegistrationOptions` return
    /// value for the corresponding server capability as well.
    Optional<Boolean> dynamic_registration;
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientDiagnosticsTagOptions {
    /// The tags supported by the client.
    std::vector<lsp::DiagnosticTag> value_set{};
};

/// The publish diagnostic client capabilities.
struct PublishDiagnosticsClientCapabilities {
    /// Whether the clients accepts diagnostics with related information.
    Optional<Boolean> related_information;

    /// Client supports the tag property to provide meta data about a diagnostic. Clients supporting
    /// tags have to handle unknown tags gracefully.
    ///
    /// @since 3.15.0
    Optional<lsp::ClientDiagnosticsTagOptions> tag_support;

    /// Whether the client interprets the version property of the `textDocument/publishDiagnostics`
    /// notification's parameter.
    ///
    /// @since 3.15.0
    Optional<Boolean> version_support;

    /// Client supports a codeDescription property
    ///
    /// @since 3.16.0
    Optional<Boolean> code_description_support;

    /// Whether code action supports the `data` property which is preserved between a
    /// `textDocument/publishDiagnostics` and `textDocument/codeAction` request.
    ///
    /// @since 3.16.0
    Optional<Boolean> data_support;
};

/// @since 3.16.0
struct CallHierarchyClientCapabilities {
    /// Whether implementation supports dynamic registration. If this is set to `true` the client
    /// supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` return
    /// value for the corresponding server capability as well.
    Optional<Boolean> dynamic_registration;
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientSemanticTokensRequestFullDelta {
    /// The client will send the `textDocument/semanticTokens/full/delta` request if the server
    /// provides a corresponding handler.
    Optional<Boolean> delta;
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientSemanticTokensRequestOptions {
    /// No documentation available
    struct Range {};

    /// The client will send the `textDocument/semanticTokens/range` request if the server provides
    /// a corresponding handler.
    Optional<OneOf<Boolean, lsp::ClientSemanticTokensRequestOptions::Range>> range;

    /// The client will send the `textDocument/semanticTokens/full` request if the server provides a
    /// corresponding handler.
    Optional<OneOf<Boolean, lsp::ClientSemanticTokensRequestFullDelta>> full;
};

/// @since 3.16.0
struct SemanticTokensClientCapabilities {
    /// Whether implementation supports dynamic registration. If this is set to `true` the client
    /// supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` return
    /// value for the corresponding server capability as well.
    Optional<Boolean> dynamic_registration;

    /// Which requests the client supports and might send to the server depending on the server's
    /// capability. Please note that clients might not show semantic tokens or degrade some of the
    /// user experience if a range or full request is advertised by the client but not provided by
    /// the server. If for example the client capability `requests.full` and `request.range` are
    /// both set to true but the server only provides a range provider the client might not render a
    /// minimap correctly or might even decide to not show any semantic tokens at all.
    lsp::ClientSemanticTokensRequestOptions requests{};

    /// The token types that the client supports.
    std::vector<String> token_types{};

    /// The token modifiers that the client supports.
    std::vector<String> token_modifiers{};

    /// The token formats the clients supports.
    std::vector<lsp::TokenFormat> formats{};

    /// Whether the client supports tokens that can overlap each other.
    Optional<Boolean> overlapping_token_support;

    /// Whether the client supports tokens that can span multiple lines.
    Optional<Boolean> multiline_token_support;

    /// Whether the client allows the server to actively cancel a semantic token request, e.g.
    /// supports returning LSPErrorCodes.ServerCancelled. If a server does the client needs to
    /// retrigger the request.
    ///
    /// @since 3.17.0
    Optional<Boolean> server_cancel_support;

    /// Whether the client uses semantic tokens to augment existing syntax tokens. If set to `true`
    /// client side created syntax tokens and semantic tokens are both used for colorization. If set
    /// to `false` the client only uses the returned semantic tokens for colorization. If the value
    /// is `undefined` then the client behavior is not specified.
    ///
    /// @since 3.17.0
    Optional<Boolean> augments_syntax_tokens;
};

/// Client capabilities for the linked editing range request.
///
/// @since 3.16.0
struct LinkedEditingRangeClientCapabilities {
    /// Whether implementation supports dynamic registration. If this is set to `true` the client
    /// supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` return
    /// value for the corresponding server capability as well.
    Optional<Boolean> dynamic_registration;
};

/// Client capabilities specific to the moniker request.
///
/// @since 3.16.0
struct MonikerClientCapabilities {
    /// Whether moniker supports dynamic registration. If this is set to `true` the client supports
    /// the new `MonikerRegistrationOptions` return value for the corresponding server capability as
    /// well.
    Optional<Boolean> dynamic_registration;
};

/// @since 3.17.0
struct TypeHierarchyClientCapabilities {
    /// Whether implementation supports dynamic registration. If this is set to `true` the client
    /// supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` return
    /// value for the corresponding server capability as well.
    Optional<Boolean> dynamic_registration;
};

/// Client capabilities specific to inline values.
///
/// @since 3.17.0
struct InlineValueClientCapabilities {
    /// Whether implementation supports dynamic registration for inline value providers.
    Optional<Boolean> dynamic_registration;
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientInlayHintResolveOptions {
    /// The properties that a client can resolve lazily.
    std::vector<String> properties{};
};

/// Inlay hint client capabilities.
///
/// @since 3.17.0
struct InlayHintClientCapabilities {
    /// Whether inlay hints support dynamic registration.
    Optional<Boolean> dynamic_registration;

    /// Indicates which properties a client can resolve lazily on an inlay hint.
    Optional<lsp::ClientInlayHintResolveOptions> resolve_support;
};

/// Client capabilities specific to diagnostic pull requests.
///
/// @since 3.17.0
struct DiagnosticClientCapabilities {
    /// Whether implementation supports dynamic registration. If this is set to `true` the client
    /// supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` return
    /// value for the corresponding server capability as well.
    Optional<Boolean> dynamic_registration;

    /// Whether the clients supports related documents for document diagnostic pulls.
    Optional<Boolean> related_document_support;
};

/// Client capabilities specific to inline completions.
///
/// @since 3.18.0
///
/// Proposed in:
struct InlineCompletionClientCapabilities {
    /// Whether implementation supports dynamic registration for inline completion providers.
    Optional<Boolean> dynamic_registration;
};

/// Text document specific client capabilities.
struct TextDocumentClientCapabilities {
    /// Defines which synchronization capabilities the client supports.
    Optional<lsp::TextDocumentSyncClientCapabilities> synchronization;

    /// Capabilities specific to the `textDocument/completion` request.
    Optional<lsp::CompletionClientCapabilities> completion;

    /// Capabilities specific to the `textDocument/hover` request.
    Optional<lsp::HoverClientCapabilities> hover;

    /// Capabilities specific to the `textDocument/signatureHelp` request.
    Optional<lsp::SignatureHelpClientCapabilities> signature_help;

    /// Capabilities specific to the `textDocument/declaration` request.
    ///
    /// @since 3.14.0
    Optional<lsp::DeclarationClientCapabilities> declaration;

    /// Capabilities specific to the `textDocument/definition` request.
    Optional<lsp::DefinitionClientCapabilities> definition;

    /// Capabilities specific to the `textDocument/typeDefinition` request.
    ///
    /// @since 3.6.0
    Optional<lsp::TypeDefinitionClientCapabilities> type_definition;

    /// Capabilities specific to the `textDocument/implementation` request.
    ///
    /// @since 3.6.0
    Optional<lsp::ImplementationClientCapabilities> implementation;

    /// Capabilities specific to the `textDocument/references` request.
    Optional<lsp::ReferenceClientCapabilities> references;

    /// Capabilities specific to the `textDocument/documentHighlight` request.
    Optional<lsp::DocumentHighlightClientCapabilities> document_highlight;

    /// Capabilities specific to the `textDocument/documentSymbol` request.
    Optional<lsp::DocumentSymbolClientCapabilities> document_symbol;

    /// Capabilities specific to the `textDocument/codeAction` request.
    Optional<lsp::CodeActionClientCapabilities> code_action;

    /// Capabilities specific to the `textDocument/codeLens` request.
    Optional<lsp::CodeLensClientCapabilities> code_lens;

    /// Capabilities specific to the `textDocument/documentLink` request.
    Optional<lsp::DocumentLinkClientCapabilities> document_link;

    /// Capabilities specific to the `textDocument/documentColor` and the
    /// `textDocument/colorPresentation` request.
    ///
    /// @since 3.6.0
    Optional<lsp::DocumentColorClientCapabilities> color_provider;

    /// Capabilities specific to the `textDocument/formatting` request.
    Optional<lsp::DocumentFormattingClientCapabilities> formatting;

    /// Capabilities specific to the `textDocument/rangeFormatting` request.
    Optional<lsp::DocumentRangeFormattingClientCapabilities> range_formatting;

    /// Capabilities specific to the `textDocument/onTypeFormatting` request.
    Optional<lsp::DocumentOnTypeFormattingClientCapabilities> on_type_formatting;

    /// Capabilities specific to the `textDocument/rename` request.
    Optional<lsp::RenameClientCapabilities> rename;

    /// Capabilities specific to the `textDocument/foldingRange` request.
    ///
    /// @since 3.10.0
    Optional<lsp::FoldingRangeClientCapabilities> folding_range;

    /// Capabilities specific to the `textDocument/selectionRange` request.
    ///
    /// @since 3.15.0
    Optional<lsp::SelectionRangeClientCapabilities> selection_range;

    /// Capabilities specific to the `textDocument/publishDiagnostics` notification.
    Optional<lsp::PublishDiagnosticsClientCapabilities> publish_diagnostics;

    /// Capabilities specific to the various call hierarchy requests.
    ///
    /// @since 3.16.0
    Optional<lsp::CallHierarchyClientCapabilities> call_hierarchy;

    /// Capabilities specific to the various semantic token request.
    ///
    /// @since 3.16.0
    Optional<lsp::SemanticTokensClientCapabilities> semantic_tokens;

    /// Capabilities specific to the `textDocument/linkedEditingRange` request.
    ///
    /// @since 3.16.0
    Optional<lsp::LinkedEditingRangeClientCapabilities> linked_editing_range;

    /// Client capabilities specific to the `textDocument/moniker` request.
    ///
    /// @since 3.16.0
    Optional<lsp::MonikerClientCapabilities> moniker;

    /// Capabilities specific to the various type hierarchy requests.
    ///
    /// @since 3.17.0
    Optional<lsp::TypeHierarchyClientCapabilities> type_hierarchy;

    /// Capabilities specific to the `textDocument/inlineValue` request.
    ///
    /// @since 3.17.0
    Optional<lsp::InlineValueClientCapabilities> inline_value;

    /// Capabilities specific to the `textDocument/inlayHint` request.
    ///
    /// @since 3.17.0
    Optional<lsp::InlayHintClientCapabilities> inlay_hint;

    /// Capabilities specific to the diagnostic pull model.
    ///
    /// @since 3.17.0
    Optional<lsp::DiagnosticClientCapabilities> diagnostic;

    /// Client capabilities specific to inline completions.
    ///
    /// @since 3.18.0
    ///
    /// Proposed in:
    Optional<lsp::InlineCompletionClientCapabilities> inline_completion;
};

/// Notebook specific client capabilities.
///
/// @since 3.17.0
struct NotebookDocumentSyncClientCapabilities {
    /// Whether implementation supports dynamic registration. If this is set to `true` the client
    /// supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` return
    /// value for the corresponding server capability as well.
    Optional<Boolean> dynamic_registration;

    /// The client supports sending execution summary data per cell.
    Optional<Boolean> execution_summary_support;
};

/// Capabilities specific to the notebook document support.
///
/// @since 3.17.0
struct NotebookDocumentClientCapabilities {
    /// Capabilities specific to notebook document synchronization
    ///
    /// @since 3.17.0
    lsp::NotebookDocumentSyncClientCapabilities synchronization{};
};

/// @since 3.18.0
///
/// Proposed in:
struct ClientShowMessageActionItemOptions {
    /// Whether the client supports additional attributes which are preserved and send back to the
    /// server in the request's response.
    Optional<Boolean> additional_properties_support;
};

/// Show message request client capabilities
struct ShowMessageRequestClientCapabilities {
    /// Capabilities specific to the `MessageActionItem` type.
    Optional<lsp::ClientShowMessageActionItemOptions> message_action_item;
};

/// Client capabilities for the showDocument request.
///
/// @since 3.16.0
struct ShowDocumentClientCapabilities {
    /// The client has support for the showDocument request.
    Boolean support{};
};

/// No documentation available
struct WindowClientCapabilities {
    /// It indicates whether the client supports server initiated progress using the
    /// `window/workDoneProgress/create` request. The capability also controls Whether client
    /// supports handling of progress notifications. If set servers are allowed to report a
    /// `workDoneProgress` property in the request specific server capabilities.
    ///
    /// @since 3.15.0
    Optional<Boolean> work_done_progress;

    /// Capabilities specific to the showMessage request.
    ///
    /// @since 3.16.0
    Optional<lsp::ShowMessageRequestClientCapabilities> show_message;

    /// Capabilities specific to the showDocument request.
    ///
    /// @since 3.16.0
    Optional<lsp::ShowDocumentClientCapabilities> show_document;
};

/// @since 3.18.0
///
/// Proposed in:
struct StaleRequestSupportOptions {
    /// The client will actively cancel the request.
    Boolean cancel{};

    /// The list of requests for which the client will retry the request if it receives a response
    /// with error code `ContentModified`
    std::vector<String> retry_on_content_modified{};
};

/// Client capabilities specific to regular expressions.
///
/// @since 3.16.0
struct RegularExpressionsClientCapabilities {
    /// The engine's name.
    String engine{};

    /// The engine's version.
    Optional<String> version;
};

/// Client capabilities specific to the used markdown parser.
///
/// @since 3.16.0
struct MarkdownClientCapabilities {
    /// The name of the parser.
    String parser{};

    /// The version of the parser.
    Optional<String> version;

    /// A list of HTML tags that the client allows / supports in Markdown.
    ///
    /// @since 3.17.0
    Optional<std::vector<String>> allowed_tags;
};

/// General client capabilities.
///
/// @since 3.16.0
struct GeneralClientCapabilities {
    /// Client capability that signals how the client handles stale requests (e.g. a request for
    /// which the client will not process the response anymore since the information is outdated).
    ///
    /// @since 3.17.0
    Optional<lsp::StaleRequestSupportOptions> stale_request_support;

    /// Client capabilities specific to regular expressions.
    ///
    /// @since 3.16.0
    Optional<lsp::RegularExpressionsClientCapabilities> regular_expressions;

    /// Client capabilities specific to the client's markdown parser.
    ///
    /// @since 3.16.0
    Optional<lsp::MarkdownClientCapabilities> markdown;

    /// The position encodings supported by the client. Client and server have to agree on the same
    /// position encoding to ensure that offsets (e.g. character position in a line) are interpreted
    /// the same on both sides. To keep the protocol backwards compatible the following applies: if
    /// the value 'utf-16' is missing from the array of position encodings servers can assume that
    /// the client supports UTF-16. UTF-16 is therefore a mandatory encoding. If omitted it defaults
    /// to ['utf-16']. Implementation considerations: since the conversion from one encoding into
    /// another requires the content of the file / line the conversion is best done where the file
    /// is read which is usually on the server side.
    ///
    /// @since 3.17.0
    Optional<std::vector<lsp::PositionEncodingKind>> position_encodings;
};

/// Defines the capabilities provided by the client.
struct ClientCapabilities {
    /// Workspace specific client capabilities.
    Optional<lsp::WorkspaceClientCapabilities> workspace;

    /// Text document specific client capabilities.
    Optional<lsp::TextDocumentClientCapabilities> text_document;

    /// Capabilities specific to the notebook document support.
    ///
    /// @since 3.17.0
    Optional<lsp::NotebookDocumentClientCapabilities> notebook_document;

    /// Window specific client capabilities.
    Optional<lsp::WindowClientCapabilities> window;

    /// General client capabilities.
    ///
    /// @since 3.16.0
    Optional<lsp::GeneralClientCapabilities> general;

    /// Experimental client capabilities.
    Optional<lsp::LSPAny> experimental;
};

/// The initialize parameters
struct InitializeParamsBase {
    /// The process Id of the parent process that started the server. Is `null` if the process has
    /// not been started by another process. If the parent process is not alive then the server
    /// should exit.
    OneOf<Integer, Null> process_id{};

    /// Information about the client
    ///
    /// @since 3.15.0
    Optional<lsp::ClientInfo> client_info;

    /// The locale the client is currently showing the user interface in. This must not necessarily
    /// be the locale of the operating system. Uses IETF language tags as the value's syntax (See
    /// https://en.wikipedia.org/wiki/IETF_language_tag)
    ///
    /// @since 3.16.0
    Optional<String> locale;

    /// The rootPath of the workspace. Is null if no folder is open.
    ///
    /// Deprecated: in favour of rootUri.
    Optional<OneOf<String, Null>> root_path;

    /// The rootUri of the workspace. Is null if no folder is open. If both `rootPath` and `rootUri`
    /// are set `rootUri` wins.
    ///
    /// Deprecated: in favour of workspaceFolders.
    OneOf<DocumentUri, Null> root_uri{};

    /// The capabilities provided by the client (editor or tool)
    lsp::ClientCapabilities capabilities{};

    /// User provided initialization options.
    Optional<lsp::LSPAny> initialization_options;

    /// The initial trace setting. If omitted trace is disabled ('off').
    Optional<lsp::TraceValues> trace;
};

/// No documentation available
struct WorkspaceFoldersInitializeParams {
    /// The workspace folders configured in the client when the server starts. This property is only
    /// available if the client supports workspace folders. It can be `null` if the client supports
    /// workspace folders but none are configured.
    ///
    /// @since 3.6.0
    Optional<OneOf<std::vector<lsp::WorkspaceFolder>, Null>> workspace_folders;
};

/// No documentation available
struct InitializeParams : lsp::InitializeParamsBase, lsp::WorkspaceFoldersInitializeParams {};

/// Save options.
struct SaveOptions {
    /// The client is supposed to include the content on save.
    Optional<Boolean> include_text;
};

/// No documentation available
struct TextDocumentSyncOptions {
    /// Open and close notifications are sent to the server. If omitted open close notification
    /// should not be sent.
    Optional<Boolean> open_close;

    /// Change notifications are sent to the server. See TextDocumentSyncKind.None,
    /// TextDocumentSyncKind.Full and TextDocumentSyncKind.Incremental. If omitted it defaults to
    /// TextDocumentSyncKind.None.
    Optional<lsp::TextDocumentSyncKind> change;

    /// If present will save notifications are sent to the server. If omitted the notification
    /// should not be sent.
    Optional<Boolean> will_save;

    /// If present will save wait until requests are sent to the server. If omitted the request
    /// should not be sent.
    Optional<Boolean> will_save_wait_until;

    /// If present save notifications are sent to the server. If omitted the notification should not
    /// be sent.
    Optional<OneOf<Boolean, lsp::SaveOptions>> save;
};

/// @since 3.18.0
///
/// Proposed in:
struct NotebookCellLanguage {
    /// No documentation available
    String language{};
};

/// @since 3.18.0
///
/// Proposed in:
struct NotebookDocumentFilterWithCells {
    /// The notebook to be synced If a string value is provided it matches against the notebook
    /// type. '*' matches every notebook.
    Optional<OneOf<String, lsp::NotebookDocumentFilter>> notebook;

    /// The cells of the matching notebook to be synced.
    std::vector<lsp::NotebookCellLanguage> cells{};
};

/// @since 3.18.0
///
/// Proposed in:
struct NotebookDocumentFilterWithNotebook {
    /// The notebook to be synced If a string value is provided it matches against the notebook
    /// type. '*' matches every notebook.
    OneOf<String, lsp::NotebookDocumentFilter> notebook{};

    /// The cells of the matching notebook to be synced.
    Optional<std::vector<lsp::NotebookCellLanguage>> cells;
};

/// Options specific to a notebook plus its cells to be synced to the server. If a selector provides
/// a notebook document filter but no cell selector all cells of a matching notebook document will
/// be synced. If a selector provides no notebook document filter but only a cell selector all
/// notebook document that contain at least one matching cell will be synced.
///
/// @since 3.17.0
struct NotebookDocumentSyncOptions {
    /// The notebooks to be synced
    std::vector<
        OneOf<lsp::NotebookDocumentFilterWithNotebook, lsp::NotebookDocumentFilterWithCells>>
        notebook_selector{};

    /// Whether save notification should be forwarded to the server. Will only be honored if mode
    /// === `notebook`.
    Optional<Boolean> save;
};

/// Registration options specific to a notebook.
///
/// @since 3.17.0
struct NotebookDocumentSyncRegistrationOptions : lsp::NotebookDocumentSyncOptions {};

/// @since 3.18.0
///
/// Proposed in:
struct ServerCompletionItemOptions {
    /// The server has support for completion item label details (see also
    /// `CompletionItemLabelDetails`) when receiving a completion item in a resolve call.
    ///
    /// @since 3.17.0
    Optional<Boolean> label_details_support;
};

/// Completion options.
struct CompletionOptions {
    /// Most tools trigger completion request automatically without explicitly requesting it using a
    /// keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user starts to type an
    /// identifier. For example if the user types `c` in a JavaScript file code complete will
    /// automatically pop up present `console` besides others as a completion item. Characters that
    /// make up identifiers don't need to be listed here. If code complete should automatically be
    /// trigger on characters not being valid inside an identifier (for example `.` in JavaScript)
    /// list them in `triggerCharacters`.
    Optional<std::vector<String>> trigger_characters;

    /// The list of all possible characters that commit a completion. This field can be used if
    /// clients don't support individual commit characters per completion item. See
    /// `ClientCapabilities.textDocument.completion.completionItem.commitCharactersSupport` If a
    /// server provides both `allCommitCharacters` and commit characters on an individual completion
    /// item the ones on the completion item win.
    ///
    /// @since 3.2.0
    Optional<std::vector<String>> all_commit_characters;

    /// The server provides support to resolve additional information for a completion item.
    Optional<Boolean> resolve_provider;

    /// The server supports the following `CompletionItem` specific capabilities.
    ///
    /// @since 3.17.0
    Optional<lsp::ServerCompletionItemOptions> completion_item;
};

/// Hover options.
struct HoverOptions {};

/// Server Capabilities for a SignatureHelpRequest.
struct SignatureHelpOptions {
    /// List of characters that trigger signature help automatically.
    Optional<std::vector<String>> trigger_characters;

    /// List of characters that re-trigger signature help. These trigger characters are only active
    /// when signature help is already showing. All trigger characters are also counted as
    /// re-trigger characters.
    ///
    /// @since 3.15.0
    Optional<std::vector<String>> retrigger_characters;
};

/// Server Capabilities for a DefinitionRequest.
struct DefinitionOptions {};

/// Reference options.
struct ReferenceOptions {};

/// Provider options for a DocumentHighlightRequest.
struct DocumentHighlightOptions {};

/// Provider options for a DocumentSymbolRequest.
struct DocumentSymbolOptions {
    /// A human-readable string that is shown when multiple outlines trees are shown for the same
    /// document.
    ///
    /// @since 3.16.0
    Optional<String> label;
};

/// Provider options for a CodeActionRequest.
struct CodeActionOptions {
    /// CodeActionKinds that this server may return. The list of kinds may be generic, such as
    /// `CodeActionKind.Refactor`, or the server may list out every specific kind they provide.
    Optional<std::vector<lsp::CodeActionKind>> code_action_kinds;

    /// The server provides support to resolve additional information for a code action.
    ///
    /// @since 3.16.0
    Optional<Boolean> resolve_provider;
};

/// Code Lens provider options of a CodeLensRequest.
struct CodeLensOptions {
    /// Code lens has a resolve provider as well.
    Optional<Boolean> resolve_provider;
};

/// Provider options for a DocumentLinkRequest.
struct DocumentLinkOptions {
    /// Document links have a resolve provider as well.
    Optional<Boolean> resolve_provider;
};

/// Server capabilities for a WorkspaceSymbolRequest.
struct WorkspaceSymbolOptions {
    /// The server provides support to resolve additional information for a workspace symbol.
    ///
    /// @since 3.17.0
    Optional<Boolean> resolve_provider;
};

/// Provider options for a DocumentFormattingRequest.
struct DocumentFormattingOptions {};

/// Provider options for a DocumentRangeFormattingRequest.
struct DocumentRangeFormattingOptions {
    /// Whether the server supports formatting multiple ranges at once.
    ///
    /// @since 3.18.0
    ///
    /// Proposed in:
    Optional<Boolean> ranges_support;
};

/// Provider options for a DocumentOnTypeFormattingRequest.
struct DocumentOnTypeFormattingOptions {
    /// A character on which formatting should be triggered, like `{`.
    String first_trigger_character{};

    /// More trigger characters.
    Optional<std::vector<String>> more_trigger_character;
};

/// Provider options for a RenameRequest.
struct RenameOptions {
    /// Renames should be checked and tested before being executed.
    ///
    /// @since version 3.12.0
    Optional<Boolean> prepare_provider;
};

/// The server capabilities of a ExecuteCommandRequest.
struct ExecuteCommandOptions {
    /// The commands to be executed on the server
    std::vector<String> commands{};
};

/// No documentation available
struct WorkspaceFoldersServerCapabilities {
    /// The server has support for workspace folders
    Optional<Boolean> supported;

    /// Whether the server wants to receive workspace folder change notifications. If a string is
    /// provided the string is treated as an ID under which the notification is registered on the
    /// client side. The ID can be used to unregister for these events using the
    /// `client/unregisterCapability` request.
    Optional<OneOf<String, Boolean>> change_notifications;
};

/// Options for notifications/requests for user operations on files.
///
/// @since 3.16.0
struct FileOperationOptions {
    /// The server is interested in receiving didCreateFiles notifications.
    Optional<lsp::FileOperationRegistrationOptions> did_create;

    /// The server is interested in receiving willCreateFiles requests.
    Optional<lsp::FileOperationRegistrationOptions> will_create;

    /// The server is interested in receiving didRenameFiles notifications.
    Optional<lsp::FileOperationRegistrationOptions> did_rename;

    /// The server is interested in receiving willRenameFiles requests.
    Optional<lsp::FileOperationRegistrationOptions> will_rename;

    /// The server is interested in receiving didDeleteFiles file notifications.
    Optional<lsp::FileOperationRegistrationOptions> did_delete;

    /// The server is interested in receiving willDeleteFiles file requests.
    Optional<lsp::FileOperationRegistrationOptions> will_delete;
};

/// Defines workspace specific capabilities of the server.
///
/// @since 3.18.0
///
/// Proposed in:
struct WorkspaceOptions {
    /// The server supports workspace folder.
    ///
    /// @since 3.6.0
    Optional<lsp::WorkspaceFoldersServerCapabilities> workspace_folders;

    /// The server is interested in notifications/requests for operations on files.
    ///
    /// @since 3.16.0
    Optional<lsp::FileOperationOptions> file_operations;
};

/// Defines the capabilities provided by a language server.
struct ServerCapabilities {
    /// The position encoding the server picked from the encodings offered by the client via the
    /// client capability `general.positionEncodings`. If the client didn't provide any position
    /// encodings the only valid value that a server can return is 'utf-16'. If omitted it defaults
    /// to 'utf-16'.
    ///
    /// @since 3.17.0
    Optional<lsp::PositionEncodingKind> position_encoding;

    /// Defines how text documents are synced. Is either a detailed structure defining each
    /// notification or for backwards compatibility the TextDocumentSyncKind number.
    Optional<OneOf<lsp::TextDocumentSyncOptions, lsp::TextDocumentSyncKind>> text_document_sync;

    /// Defines how notebook documents are synced.
    ///
    /// @since 3.17.0
    Optional<OneOf<lsp::NotebookDocumentSyncOptions, lsp::NotebookDocumentSyncRegistrationOptions>>
        notebook_document_sync;

    /// The server provides completion support.
    Optional<lsp::CompletionOptions> completion_provider;

    /// The server provides hover support.
    Optional<OneOf<Boolean, lsp::HoverOptions>> hover_provider;

    /// The server provides signature help support.
    Optional<lsp::SignatureHelpOptions> signature_help_provider;

    /// The server provides Goto Declaration support.
    Optional<OneOf<Boolean, lsp::DeclarationOptions, lsp::DeclarationRegistrationOptions>>
        declaration_provider;

    /// The server provides goto definition support.
    Optional<OneOf<Boolean, lsp::DefinitionOptions>> definition_provider;

    /// The server provides Goto Type Definition support.
    Optional<OneOf<Boolean, lsp::TypeDefinitionOptions, lsp::TypeDefinitionRegistrationOptions>>
        type_definition_provider;

    /// The server provides Goto Implementation support.
    Optional<OneOf<Boolean, lsp::ImplementationOptions, lsp::ImplementationRegistrationOptions>>
        implementation_provider;

    /// The server provides find references support.
    Optional<OneOf<Boolean, lsp::ReferenceOptions>> references_provider;

    /// The server provides document highlight support.
    Optional<OneOf<Boolean, lsp::DocumentHighlightOptions>> document_highlight_provider;

    /// The server provides document symbol support.
    Optional<OneOf<Boolean, lsp::DocumentSymbolOptions>> document_symbol_provider;

    /// The server provides code actions. CodeActionOptions may only be specified if the client
    /// states that it supports `codeActionLiteralSupport` in its initial `initialize` request.
    Optional<OneOf<Boolean, lsp::CodeActionOptions>> code_action_provider;

    /// The server provides code lens.
    Optional<lsp::CodeLensOptions> code_lens_provider;

    /// The server provides document link support.
    Optional<lsp::DocumentLinkOptions> document_link_provider;

    /// The server provides color provider support.
    Optional<OneOf<Boolean, lsp::DocumentColorOptions, lsp::DocumentColorRegistrationOptions>>
        color_provider;

    /// The server provides workspace symbol support.
    Optional<OneOf<Boolean, lsp::WorkspaceSymbolOptions>> workspace_symbol_provider;

    /// The server provides document formatting.
    Optional<OneOf<Boolean, lsp::DocumentFormattingOptions>> document_formatting_provider;

    /// The server provides document range formatting.
    Optional<OneOf<Boolean, lsp::DocumentRangeFormattingOptions>>
        document_range_formatting_provider;

    /// The server provides document formatting on typing.
    Optional<lsp::DocumentOnTypeFormattingOptions> document_on_type_formatting_provider;

    /// The server provides rename support. RenameOptions may only be specified if the client states
    /// that it supports `prepareSupport` in its initial `initialize` request.
    Optional<OneOf<Boolean, lsp::RenameOptions>> rename_provider;

    /// The server provides folding provider support.
    Optional<OneOf<Boolean, lsp::FoldingRangeOptions, lsp::FoldingRangeRegistrationOptions>>
        folding_range_provider;

    /// The server provides selection range support.
    Optional<OneOf<Boolean, lsp::SelectionRangeOptions, lsp::SelectionRangeRegistrationOptions>>
        selection_range_provider;

    /// The server provides execute command support.
    Optional<lsp::ExecuteCommandOptions> execute_command_provider;

    /// The server provides call hierarchy support.
    ///
    /// @since 3.16.0
    Optional<OneOf<Boolean, lsp::CallHierarchyOptions, lsp::CallHierarchyRegistrationOptions>>
        call_hierarchy_provider;

    /// The server provides linked editing range support.
    ///
    /// @since 3.16.0
    Optional<
        OneOf<Boolean, lsp::LinkedEditingRangeOptions, lsp::LinkedEditingRangeRegistrationOptions>>
        linked_editing_range_provider;

    /// The server provides semantic tokens support.
    ///
    /// @since 3.16.0
    Optional<OneOf<lsp::SemanticTokensOptions, lsp::SemanticTokensRegistrationOptions>>
        semantic_tokens_provider;

    /// The server provides moniker support.
    ///
    /// @since 3.16.0
    Optional<OneOf<Boolean, lsp::MonikerOptions, lsp::MonikerRegistrationOptions>> moniker_provider;

    /// The server provides type hierarchy support.
    ///
    /// @since 3.17.0
    Optional<OneOf<Boolean, lsp::TypeHierarchyOptions, lsp::TypeHierarchyRegistrationOptions>>
        type_hierarchy_provider;

    /// The server provides inline values.
    ///
    /// @since 3.17.0
    Optional<OneOf<Boolean, lsp::InlineValueOptions, lsp::InlineValueRegistrationOptions>>
        inline_value_provider;

    /// The server provides inlay hints.
    ///
    /// @since 3.17.0
    Optional<OneOf<Boolean, lsp::InlayHintOptions, lsp::InlayHintRegistrationOptions>>
        inlay_hint_provider;

    /// The server has support for pull model diagnostics.
    ///
    /// @since 3.17.0
    Optional<OneOf<lsp::DiagnosticOptions, lsp::DiagnosticRegistrationOptions>> diagnostic_provider;

    /// Inline completion options used during static registration.
    ///
    /// @since 3.18.0
    ///
    /// Proposed in:
    Optional<OneOf<Boolean, lsp::InlineCompletionOptions>> inline_completion_provider;

    /// Workspace specific server capabilities.
    Optional<lsp::WorkspaceOptions> workspace;

    /// Experimental server capabilities.
    Optional<lsp::LSPAny> experimental;
};

/// Information about the server
///
/// @since 3.15.0
///
/// @since 3.18.0 ServerInfo type name added.
///
/// Proposed in:
struct ServerInfo {
    /// The name of the server as defined by the server.
    String name{};

    /// The server's version as defined by the server.
    Optional<String> version;
};

/// The result returned from an initialize request.
struct InitializeResult {
    /// The capabilities the language server provides.
    lsp::ServerCapabilities capabilities{};

    /// Information about the server.
    ///
    /// @since 3.15.0
    Optional<lsp::ServerInfo> server_info;
};

/// The data type of the ResponseError if the initialize request fails.
struct InitializeError {
    /// Indicates whether the client execute the following retry logic: (1) show the message
    /// provided by the ResponseError to the user (2) user selects retry or cancel (3) if user
    /// selected retry the initialize method is sent again.
    Boolean retry{};
};

/// No documentation available
struct InitializedParams {};

/// The parameters of a change configuration notification.
struct DidChangeConfigurationParams {
    /// The actual changed settings
    lsp::LSPAny settings{};
};

/// No documentation available
struct DidChangeConfigurationRegistrationOptions {
    /// No documentation available
    Optional<OneOf<String, std::vector<String>>> section;
};

/// The parameters of a notification message.
struct ShowMessageParams {
    /// The message type. See MessageType
    lsp::MessageType type{};

    /// The actual message.
    String message{};
};

/// No documentation available
struct MessageActionItem {
    /// A short title like 'Retry', 'Open Log' etc.
    String title{};
};

/// No documentation available
struct ShowMessageRequestParams {
    /// The message type. See MessageType
    lsp::MessageType type{};

    /// The actual message.
    String message{};

    /// The message action items to present.
    Optional<std::vector<lsp::MessageActionItem>> actions;
};

/// The log message parameters.
struct LogMessageParams {
    /// The message type. See MessageType
    lsp::MessageType type{};

    /// The actual message.
    String message{};
};

/// The parameters sent in an open text document notification
struct DidOpenTextDocumentParams {
    /// The document that was opened.
    lsp::TextDocumentItem text_document{};
};

/// The change text document notification's parameters.
struct DidChangeTextDocumentParams {
    /// The document that did change. The version number points to the version after all provided
    /// content changes have been applied.
    lsp::VersionedTextDocumentIdentifier text_document{};

    /// The actual content changes. The content changes describe single state changes to the
    /// document. So if there are two content changes c1 (at array index 0) and c2 (at array index
    /// 1) for a document in state S then c1 moves the document from S to S' and c2 from S' to S''.
    /// So c1 is computed on the state S and c2 is computed on the state S'. To mirror the content
    /// of a document using change events use the following approach: - start with the same initial
    /// content - apply the 'textDocument/didChange' notifications in the order you receive them. -
    /// apply the `TextDocumentContentChangeEvent`s in a single notification in the order  you
    /// receive them.
    std::vector<lsp::TextDocumentContentChangeEvent> content_changes{};
};

/// Describe options to be used when registered for text document change events.
struct TextDocumentChangeRegistrationOptions : lsp::TextDocumentRegistrationOptions {
    /// How documents are synced to the server.
    lsp::TextDocumentSyncKind sync_kind{};
};

/// The parameters sent in a close text document notification
struct DidCloseTextDocumentParams {
    /// The document that was closed.
    lsp::TextDocumentIdentifier text_document{};
};

/// The parameters sent in a save text document notification
struct DidSaveTextDocumentParams {
    /// The document that was saved.
    lsp::TextDocumentIdentifier text_document{};

    /// Optional the content when saved. Depends on the includeText value when the save notification
    /// was requested.
    Optional<String> text;
};

/// Save registration options.
struct TextDocumentSaveRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                             lsp::SaveOptions {};

/// The parameters sent in a will save text document notification.
struct WillSaveTextDocumentParams {
    /// The document that will be saved.
    lsp::TextDocumentIdentifier text_document{};

    /// The 'TextDocumentSaveReason'.
    lsp::TextDocumentSaveReason reason{};
};

/// An event describing a file change.
struct FileEvent {
    /// The file's uri.
    DocumentUri uri{};

    /// The change type.
    lsp::FileChangeType type{};
};

/// The watched files change notification's parameters.
struct DidChangeWatchedFilesParams {
    /// The actual file events.
    std::vector<lsp::FileEvent> changes{};
};

/// No documentation available
struct FileSystemWatcher {
    /// The glob pattern to watch. See GlobPattern glob pattern for more detail.
    ///
    /// @since 3.17.0 support for relative patterns.
    lsp::GlobPattern glob_pattern{};

    /// The kind of events of interest. If omitted it defaults to WatchKind.Create |
    /// WatchKind.Change | WatchKind.Delete which is 7.
    Optional<lsp::WatchKind> kind;
};

/// Describe options to be used when registered for text document change events.
struct DidChangeWatchedFilesRegistrationOptions {
    /// The watchers to register.
    std::vector<lsp::FileSystemWatcher> watchers{};
};

/// The publish diagnostic notification's parameters.
struct PublishDiagnosticsParams {
    /// The URI for which diagnostic information is reported.
    DocumentUri uri{};

    /// Optional the version number of the document the diagnostics are published for.
    ///
    /// @since 3.15.0
    Optional<Integer> version;

    /// An array of diagnostic information items.
    std::vector<lsp::Diagnostic> diagnostics{};
};

/// Contains additional information about the context in which a completion request is triggered.
struct CompletionContext {
    /// How the completion was triggered.
    lsp::CompletionTriggerKind trigger_kind{};

    /// The trigger character (a single character) that has trigger code complete. Is undefined if
    /// `triggerKind !== CompletionTriggerKind.TriggerCharacter`
    Optional<String> trigger_character;
};

/// Completion parameters
struct CompletionParams : lsp::TextDocumentPositionParams {
    /// The completion context. This is only available it the client specifies to send this using
    /// the client capability `textDocument.completion.contextSupport === true`
    Optional<lsp::CompletionContext> context;
};

/// Additional details for a completion item label.
///
/// @since 3.17.0
struct CompletionItemLabelDetails {
    /// An optional string which is rendered less prominently directly after CompletionItem.label
    /// label, without any spacing. Should be used for function signatures and type annotations.
    Optional<String> detail;

    /// An optional string which is rendered less prominently after CompletionItem.detail. Should be
    /// used for fully qualified names and file paths.
    Optional<String> description;
};

/// A special text edit to provide an insert and a replace operation.
///
/// @since 3.16.0
struct InsertReplaceEdit {
    /// The string to be inserted.
    String new_text{};

    /// The range if the insert is requested
    lsp::Range insert{};

    /// The range if the replace is requested.
    lsp::Range replace{};
};

/// A completion item represents a text snippet that is proposed to complete text that is being
/// typed.
struct CompletionItem {
    /// The label of this completion item. The label property is also by default the text that is
    /// inserted when selecting this completion. If label details are provided the label itself
    /// should be an unqualified name of the completion item.
    String label{};

    /// Additional details for the label
    ///
    /// @since 3.17.0
    Optional<lsp::CompletionItemLabelDetails> label_details;

    /// The kind of this completion item. Based of the kind an icon is chosen by the editor.
    Optional<lsp::CompletionItemKind> kind;

    /// Tags for this completion item.
    ///
    /// @since 3.15.0
    Optional<std::vector<lsp::CompletionItemTag>> tags;

    /// A human-readable string with additional information about this item, like type or symbol
    /// information.
    Optional<String> detail;

    /// A human-readable string that represents a doc-comment.
    Optional<OneOf<String, lsp::MarkupContent>> documentation;

    /// Indicates if this item is deprecated.
    ///
    /// Deprecated: Use `tags` instead.
    Optional<Boolean> deprecated;

    /// Select this item when showing. *Note* that only one completion item can be selected and that
    /// the tool / client decides which item that is. The rule is that the *first* item of those
    /// that match best is selected.
    Optional<Boolean> preselect;

    /// A string that should be used when comparing this item with other items. When `falsy` the
    /// CompletionItem.label label is used.
    Optional<String> sort_text;

    /// A string that should be used when filtering a set of completion items. When `falsy` the
    /// CompletionItem.label label is used.
    Optional<String> filter_text;

    /// A string that should be inserted into a document when selecting this completion. When
    /// `falsy` the CompletionItem.label label is used. The `insertText` is subject to
    /// interpretation by the client side. Some tools might not take the string literally. For
    /// example VS Code when code complete is requested in this example `con<cursor position>` and a
    /// completion item with an `insertText` of `console` is provided it will only insert `sole`.
    /// Therefore it is recommended to use `textEdit` instead since it avoids additional client side
    /// interpretation.
    Optional<String> insert_text;

    /// The format of the insert text. The format applies to both the `insertText` property and the
    /// `newText` property of a provided `textEdit`. If omitted defaults to
    /// `InsertTextFormat.PlainText`. Please note that the insertTextFormat doesn't apply to
    /// `additionalTextEdits`.
    Optional<lsp::InsertTextFormat> insert_text_format;

    /// How whitespace and indentation is handled during completion item insertion. If not provided
    /// the clients default value depends on the `textDocument.completion.insertTextMode` client
    /// capability.
    ///
    /// @since 3.16.0
    Optional<lsp::InsertTextMode> insert_text_mode;

    /// An TextEdit edit which is applied to a document when selecting this completion. When an edit
    /// is provided the value of CompletionItem.insertText insertText is ignored. Most editors
    /// support two different operations when accepting a completion item. One is to insert a
    /// completion text and the other is to replace an existing text with a completion text. Since
    /// this can usually not be predetermined by a server it can report both ranges. Clients need to
    /// signal support for `InsertReplaceEdits` via the
    /// `textDocument.completion.insertReplaceSupport` client capability property. *Note 1:* The
    /// text edit's range as well as both ranges from an insert replace edit must be a [single line]
    /// and they must contain the position at which completion has been requested. *Note 2:* If an
    /// `InsertReplaceEdit` is returned the edit's insert range must be a prefix of the edit's
    /// replace range, that means it must be contained and starting at the same position.
    ///
    /// @since 3.16.0 additional type `InsertReplaceEdit`
    Optional<OneOf<lsp::TextEdit, lsp::InsertReplaceEdit>> text_edit;

    /// The edit text used if the completion item is part of a CompletionList and CompletionList
    /// defines an item default for the text edit range. Clients will only honor this property if
    /// they opt into completion list item defaults using the capability
    /// `completionList.itemDefaults`. If not provided and a list's default range is provided the
    /// label property is used as a text.
    ///
    /// @since 3.17.0
    Optional<String> text_edit_text;

    /// An optional array of additional TextEdit text edits that are applied when selecting this
    /// completion. Edits must not overlap (including the same insert position) with the main
    /// CompletionItem.textEdit edit nor with themselves. Additional text edits should be used to
    /// change text unrelated to the current cursor position (for example adding an import statement
    /// at the top of the file if the completion item will insert an unqualified type).
    Optional<std::vector<lsp::TextEdit>> additional_text_edits;

    /// An optional set of characters that when pressed while this completion is active will accept
    /// it first and then type that character. *Note* that all commit characters should have
    /// `length=1` and that superfluous characters will be ignored.
    Optional<std::vector<String>> commit_characters;

    /// An optional Command command that is executed *after* inserting this completion. *Note* that
    /// additional modifications to the current document should be described with the
    /// CompletionItem.additionalTextEdits additionalTextEdits-property.
    Optional<lsp::Command> command;

    /// A data entry field that is preserved on a completion item between a CompletionRequest and a
    /// CompletionResolveRequest.
    Optional<lsp::LSPAny> data;
};

/// Edit range variant that includes ranges for insert and replace operations.
///
/// @since 3.18.0
///
/// Proposed in:
struct EditRangeWithInsertReplace {
    /// No documentation available
    lsp::Range insert{};

    /// No documentation available
    lsp::Range replace{};
};

/// In many cases the items of an actual completion result share the same value for properties like
/// `commitCharacters` or the range of a text edit. A completion list can therefore define item
/// defaults which will be used if a completion item itself doesn't specify the value. If a
/// completion list specifies a default value and a completion item also specifies a corresponding
/// value the one from the item is used. Servers are only allowed to return default values if the
/// client signals support for this via the `completionList.itemDefaults` capability.
///
/// @since 3.17.0
struct CompletionItemDefaults {
    /// A default commit character set.
    ///
    /// @since 3.17.0
    Optional<std::vector<String>> commit_characters;

    /// A default edit range.
    ///
    /// @since 3.17.0
    Optional<OneOf<lsp::Range, lsp::EditRangeWithInsertReplace>> edit_range;

    /// A default insert text format.
    ///
    /// @since 3.17.0
    Optional<lsp::InsertTextFormat> insert_text_format;

    /// A default insert text mode.
    ///
    /// @since 3.17.0
    Optional<lsp::InsertTextMode> insert_text_mode;

    /// A default data value.
    ///
    /// @since 3.17.0
    Optional<lsp::LSPAny> data;
};

/// Represents a collection of CompletionItem completion items to be presented in the editor.
struct CompletionList {
    /// This list it not complete. Further typing results in recomputing this list. Recomputed lists
    /// have all their items replaced (not appended) in the incomplete completion sessions.
    Boolean is_incomplete{};

    /// In many cases the items of an actual completion result share the same value for properties
    /// like `commitCharacters` or the range of a text edit. A completion list can therefore define
    /// item defaults which will be used if a completion item itself doesn't specify the value. If a
    /// completion list specifies a default value and a completion item also specifies a
    /// corresponding value the one from the item is used. Servers are only allowed to return
    /// default values if the client signals support for this via the `completionList.itemDefaults`
    /// capability.
    ///
    /// @since 3.17.0
    Optional<lsp::CompletionItemDefaults> item_defaults;

    /// The completion items.
    std::vector<lsp::CompletionItem> items{};
};

/// Registration options for a CompletionRequest.
struct CompletionRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                       lsp::CompletionOptions {};

/// Parameters for a HoverRequest.
struct HoverParams : lsp::TextDocumentPositionParams {};

/// The result of a hover request.
struct Hover {
    /// The hover's content
    OneOf<lsp::MarkupContent, lsp::MarkedString, std::vector<lsp::MarkedString>> contents{};

    /// An optional range inside the text document that is used to visualize the hover, e.g. by
    /// changing the background color.
    Optional<lsp::Range> range;
};

/// Registration options for a HoverRequest.
struct HoverRegistrationOptions : lsp::TextDocumentRegistrationOptions, lsp::HoverOptions {};

/// Represents a parameter of a callable-signature. A parameter can have a label and a doc-comment.
struct ParameterInformation {
    /// The label of this parameter information. Either a string or an inclusive start and exclusive
    /// end offsets within its containing signature label. (see SignatureInformation.label). The
    /// offsets are based on a UTF-16 string representation as `Position` and `Range` does. *Note*:
    /// a label of type string should be a substring of its containing signature label. Its intended
    /// use case is to highlight the parameter label part in the `SignatureInformation.label`.
    OneOf<String, std::tuple<Uinteger, Uinteger>> label{};

    /// The human-readable doc-comment of this parameter. Will be shown in the UI but can be
    /// omitted.
    Optional<OneOf<String, lsp::MarkupContent>> documentation;
};

/// Represents the signature of something callable. A signature can have a label, like a
/// function-name, a doc-comment, and a set of parameters.
struct SignatureInformation {
    /// The label of this signature. Will be shown in the UI.
    String label{};

    /// The human-readable doc-comment of this signature. Will be shown in the UI but can be
    /// omitted.
    Optional<OneOf<String, lsp::MarkupContent>> documentation;

    /// The parameters of this signature.
    Optional<std::vector<lsp::ParameterInformation>> parameters;

    /// The index of the active parameter. If provided, this is used in place of
    /// `SignatureHelp.activeParameter`.
    ///
    /// @since 3.16.0
    Optional<Uinteger> active_parameter;
};

/// Signature help represents the signature of something callable. There can be multiple signature
/// but only one active and only one active parameter.
struct SignatureHelp {
    /// One or more signatures.
    std::vector<lsp::SignatureInformation> signatures{};

    /// The active signature. If omitted or the value lies outside the range of `signatures` the
    /// value defaults to zero or is ignored if the `SignatureHelp` has no signatures. Whenever
    /// possible implementors should make an active decision about the active signature and
    /// shouldn't rely on a default value. In future version of the protocol this property might
    /// become mandatory to better express this.
    Optional<Uinteger> active_signature;

    /// The active parameter of the active signature. If omitted or the value lies outside the range
    /// of `signatures[activeSignature].parameters` defaults to 0 if the active signature has
    /// parameters. If the active signature has no parameters it is ignored. In future version of
    /// the protocol this property might become mandatory to better express the active parameter if
    /// the active signature does have any.
    Optional<Uinteger> active_parameter;
};

/// Additional information about the context in which a signature help request was triggered.
///
/// @since 3.15.0
struct SignatureHelpContext {
    /// Action that caused signature help to be triggered.
    lsp::SignatureHelpTriggerKind trigger_kind{};

    /// Character that caused signature help to be triggered. This is undefined when `triggerKind
    /// !== SignatureHelpTriggerKind.TriggerCharacter`
    Optional<String> trigger_character;

    /// `true` if signature help was already showing when it was triggered. Retriggers occurs when
    /// the signature help is already active and can be caused by actions such as typing a trigger
    /// character, a cursor move, or document content changes.
    Boolean is_retrigger{};

    /// The currently active `SignatureHelp`. The `activeSignatureHelp` has its
    /// `SignatureHelp.activeSignature` field updated based on the user navigating through available
    /// signatures.
    Optional<lsp::SignatureHelp> active_signature_help;
};

/// Parameters for a SignatureHelpRequest.
struct SignatureHelpParams : lsp::TextDocumentPositionParams {
    /// The signature help context. This is only available if the client specifies to send this
    /// using the client capability `textDocument.signatureHelp.contextSupport === true`
    ///
    /// @since 3.15.0
    Optional<lsp::SignatureHelpContext> context;
};

/// Registration options for a SignatureHelpRequest.
struct SignatureHelpRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                          lsp::SignatureHelpOptions {};

/// Parameters for a DefinitionRequest.
struct DefinitionParams : lsp::TextDocumentPositionParams {};

/// Registration options for a DefinitionRequest.
struct DefinitionRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                       lsp::DefinitionOptions {};

/// Value-object that contains additional information when requesting references.
struct ReferenceContext {
    /// Include the declaration of the current symbol.
    Boolean include_declaration{};
};

/// Parameters for a ReferencesRequest.
struct ReferenceParams : lsp::TextDocumentPositionParams {
    /// No documentation available
    lsp::ReferenceContext context{};
};

/// Registration options for a ReferencesRequest.
struct ReferenceRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                      lsp::ReferenceOptions {};

/// Parameters for a DocumentHighlightRequest.
struct DocumentHighlightParams : lsp::TextDocumentPositionParams {};

/// A document highlight is a range inside a text document which deserves special attention. Usually
/// a document highlight is visualized by changing the background color of its range.
struct DocumentHighlight {
    /// The range this highlight applies to.
    lsp::Range range{};

    /// The highlight kind, default is DocumentHighlightKind.Text text.
    Optional<lsp::DocumentHighlightKind> kind;
};

/// Registration options for a DocumentHighlightRequest.
struct DocumentHighlightRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                              lsp::DocumentHighlightOptions {};

/// Parameters for a DocumentSymbolRequest.
struct DocumentSymbolParams {
    /// The text document.
    lsp::TextDocumentIdentifier text_document{};
};

/// A base for all symbol information.
struct BaseSymbolInformation {
    /// The name of this symbol.
    String name{};

    /// The kind of this symbol.
    lsp::SymbolKind kind{};

    /// Tags for this symbol.
    ///
    /// @since 3.16.0
    Optional<std::vector<lsp::SymbolTag>> tags;

    /// The name of the symbol containing this symbol. This information is for user interface
    /// purposes (e.g. to render a qualifier in the user interface if necessary). It can't be used
    /// to re-infer a hierarchy for the document symbols.
    Optional<String> container_name;
};

/// Represents information about programming constructs like variables, classes, interfaces etc.
struct SymbolInformation : lsp::BaseSymbolInformation {
    /// Indicates if this symbol is deprecated.
    ///
    /// Deprecated: Use tags instead
    Optional<Boolean> deprecated;

    /// The location of this symbol. The location's range is used by a tool to reveal the location
    /// in the editor. If the symbol is selected in the tool the range's start information is used
    /// to position the cursor. So the range usually spans more than the actual symbol's name and
    /// does normally include things like visibility modifiers. The range doesn't have to denote a
    /// node range in the sense of an abstract syntax tree. It can therefore not be used to
    /// re-construct a hierarchy of the symbols.
    lsp::Location location{};
};

/// Represents programming constructs like variables, classes, interfaces etc. that appear in a
/// document. Document symbols can be hierarchical and they have two ranges: one that encloses its
/// definition and one that points to its most interesting range, e.g. the range of an identifier.
struct DocumentSymbol {
    /// The name of this symbol. Will be displayed in the user interface and therefore must not be
    /// an empty string or a string only consisting of white spaces.
    String name{};

    /// More detail for this symbol, e.g the signature of a function.
    Optional<String> detail;

    /// The kind of this symbol.
    lsp::SymbolKind kind{};

    /// Tags for this document symbol.
    ///
    /// @since 3.16.0
    Optional<std::vector<lsp::SymbolTag>> tags;

    /// Indicates if this symbol is deprecated.
    ///
    /// Deprecated: Use tags instead
    Optional<Boolean> deprecated;

    /// The range enclosing this symbol not including leading/trailing whitespace but everything
    /// else like comments. This information is typically used to determine if the clients cursor is
    /// inside the symbol to reveal in the symbol in the UI.
    lsp::Range range{};

    /// The range that should be selected and revealed when this symbol is being picked, e.g the
    /// name of a function. Must be contained by the `range`.
    lsp::Range selection_range{};

    /// Children of this symbol, e.g. properties of a class.
    Optional<std::vector<lsp::DocumentSymbol>> children;
};

/// Registration options for a DocumentSymbolRequest.
struct DocumentSymbolRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                           lsp::DocumentSymbolOptions {};

/// Contains additional diagnostic information about the context in which a
/// CodeActionProvider.provideCodeActions code action is run.
struct CodeActionContext {
    /// An array of diagnostics known on the client side overlapping the range provided to the
    /// `textDocument/codeAction` request. They are provided so that the server knows which errors
    /// are currently presented to the user for the given range. There is no guarantee that these
    /// accurately reflect the error state of the resource. The primary parameter to compute code
    /// actions is the provided range.
    std::vector<lsp::Diagnostic> diagnostics{};

    /// Requested kind of actions to return. Actions not of this kind are filtered out by the client
    /// before being shown. So servers can omit computing them.
    Optional<std::vector<lsp::CodeActionKind>> only;

    /// The reason why code actions were requested.
    ///
    /// @since 3.17.0
    Optional<lsp::CodeActionTriggerKind> trigger_kind;
};

/// The parameters of a CodeActionRequest.
struct CodeActionParams {
    /// The document in which the command was invoked.
    lsp::TextDocumentIdentifier text_document{};

    /// The range for which the command was invoked.
    lsp::Range range{};

    /// Context carrying additional information.
    lsp::CodeActionContext context{};
};

/// Captures why the code action is currently disabled.
///
/// @since 3.18.0
///
/// Proposed in:
struct CodeActionDisabled {
    /// Human readable description of why the code action is currently disabled. This is displayed
    /// in the code actions UI.
    String reason{};
};

/// A code action represents a change that can be performed in code, e.g. to fix a problem or to
/// refactor code. A CodeAction must set either `edit` and/or a `command`. If both are supplied, the
/// `edit` is applied first, then the `command` is executed.
struct CodeAction {
    /// A short, human-readable, title for this code action.
    String title{};

    /// The kind of the code action. Used to filter code actions.
    Optional<lsp::CodeActionKind> kind;

    /// The diagnostics that this code action resolves.
    Optional<std::vector<lsp::Diagnostic>> diagnostics;

    /// Marks this as a preferred action. Preferred actions are used by the `auto fix` command and
    /// can be targeted by keybindings. A quick fix should be marked preferred if it properly
    /// addresses the underlying error. A refactoring should be marked preferred if it is the most
    /// reasonable choice of actions to take.
    ///
    /// @since 3.15.0
    Optional<Boolean> is_preferred;

    /// Marks that the code action cannot currently be applied. Clients should follow the following
    /// guidelines regarding disabled code actions:  - Disabled code actions are not shown in
    /// automatic
    /// [lightbulbs](https://code.visualstudio.com/docs/editor/editingevolved#_code-action)   code
    /// action menus.  - Disabled actions are shown as faded out in the code action menu when the
    /// user requests a more specific type   of code action, such as refactorings.  - If the user
    /// has a
    /// [keybinding](https://code.visualstudio.com/docs/editor/refactoring#_keybindings-for-code-actions)
    /// that auto applies a code action and only disabled code actions are returned, the client
    /// should show the user an   error message with `reason` in the editor.
    ///
    /// @since 3.16.0
    Optional<lsp::CodeActionDisabled> disabled;

    /// The workspace edit this code action performs.
    Optional<lsp::WorkspaceEdit> edit;

    /// A command this code action executes. If a code action provides an edit and a command, first
    /// the edit is executed and then the command.
    Optional<lsp::Command> command;

    /// A data entry field that is preserved on a code action between a `textDocument/codeAction`
    /// and a `codeAction/resolve` request.
    ///
    /// @since 3.16.0
    Optional<lsp::LSPAny> data;
};

/// Registration options for a CodeActionRequest.
struct CodeActionRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                       lsp::CodeActionOptions {};

/// The parameters of a WorkspaceSymbolRequest.
struct WorkspaceSymbolParams {
    /// A query string to filter symbols by. Clients may send an empty string here to request all
    /// symbols.
    String query{};
};

/// Location with only uri and does not include range.
///
/// @since 3.18.0
///
/// Proposed in:
struct LocationUriOnly {
    /// No documentation available
    DocumentUri uri{};
};

/// A special workspace symbol that supports locations without a range. See also SymbolInformation.
///
/// @since 3.17.0
struct WorkspaceSymbol : lsp::BaseSymbolInformation {
    /// The location of the symbol. Whether a server is allowed to return a location without a range
    /// depends on the client capability `workspace.symbol.resolveSupport`. See
    /// SymbolInformation#location for more details.
    OneOf<lsp::Location, lsp::LocationUriOnly> location{};

    /// A data entry field that is preserved on a workspace symbol between a workspace symbol
    /// request and a workspace symbol resolve request.
    Optional<lsp::LSPAny> data;
};

/// Registration options for a WorkspaceSymbolRequest.
struct WorkspaceSymbolRegistrationOptions : lsp::WorkspaceSymbolOptions {};

/// The parameters of a CodeLensRequest.
struct CodeLensParams {
    /// The document to request code lens for.
    lsp::TextDocumentIdentifier text_document{};
};

/// A code lens represents a Command command that should be shown along with source text, like the
/// number of references, a way to run tests, etc. A code lens is _unresolved_ when no command is
/// associated to it. For performance reasons the creation of a code lens and resolving should be
/// done in two stages.
struct CodeLens {
    /// The range in which this code lens is valid. Should only span a single line.
    lsp::Range range{};

    /// The command this code lens represents.
    Optional<lsp::Command> command;

    /// A data entry field that is preserved on a code lens item between a CodeLensRequest and a
    /// CodeLensResolveRequest
    Optional<lsp::LSPAny> data;
};

/// Registration options for a CodeLensRequest.
struct CodeLensRegistrationOptions : lsp::TextDocumentRegistrationOptions, lsp::CodeLensOptions {};

/// The parameters of a DocumentLinkRequest.
struct DocumentLinkParams {
    /// The document to provide document links for.
    lsp::TextDocumentIdentifier text_document{};
};

/// A document link is a range in a text document that links to an internal or external resource,
/// like another text document or a web site.
struct DocumentLink {
    /// The range this link applies to.
    lsp::Range range{};

    /// The uri this link points to. If missing a resolve request is sent later.
    Optional<Uri> target;

    /// The tooltip text when you hover over this link. If a tooltip is provided, is will be
    /// displayed in a string that includes instructions on how to trigger the link, such as `{0}
    /// (ctrl + click)`. The specific instructions vary depending on OS, user settings, and
    /// localization.
    ///
    /// @since 3.15.0
    Optional<String> tooltip;

    /// A data entry field that is preserved on a document link between a DocumentLinkRequest and a
    /// DocumentLinkResolveRequest.
    Optional<lsp::LSPAny> data;
};

/// Registration options for a DocumentLinkRequest.
struct DocumentLinkRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                         lsp::DocumentLinkOptions {};

/// Value-object describing what options formatting should use.
struct FormattingOptions {
    /// Size of a tab in spaces.
    Uinteger tab_size{};

    /// Prefer spaces over tabs.
    Boolean insert_spaces{};

    /// Trim trailing whitespace on a line.
    ///
    /// @since 3.15.0
    Optional<Boolean> trim_trailing_whitespace;

    /// Insert a newline character at the end of the file if one does not exist.
    ///
    /// @since 3.15.0
    Optional<Boolean> insert_final_newline;

    /// Trim all newlines after the final newline at the end of the file.
    ///
    /// @since 3.15.0
    Optional<Boolean> trim_final_newlines;
};

/// The parameters of a DocumentFormattingRequest.
struct DocumentFormattingParams {
    /// The document to format.
    lsp::TextDocumentIdentifier text_document{};

    /// The format options.
    lsp::FormattingOptions options{};
};

/// Registration options for a DocumentFormattingRequest.
struct DocumentFormattingRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                               lsp::DocumentFormattingOptions {};

/// The parameters of a DocumentRangeFormattingRequest.
struct DocumentRangeFormattingParams {
    /// The document to format.
    lsp::TextDocumentIdentifier text_document{};

    /// The range to format
    lsp::Range range{};

    /// The format options
    lsp::FormattingOptions options{};
};

/// Registration options for a DocumentRangeFormattingRequest.
struct DocumentRangeFormattingRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                                    lsp::DocumentRangeFormattingOptions {};

/// The parameters of a DocumentRangesFormattingRequest.
///
/// @since 3.18.0
///
/// Proposed in:
struct DocumentRangesFormattingParams {
    /// The document to format.
    lsp::TextDocumentIdentifier text_document{};

    /// The ranges to format
    std::vector<lsp::Range> ranges{};

    /// The format options
    lsp::FormattingOptions options{};
};

/// The parameters of a DocumentOnTypeFormattingRequest.
struct DocumentOnTypeFormattingParams {
    /// The document to format.
    lsp::TextDocumentIdentifier text_document{};

    /// The position around which the on type formatting should happen. This is not necessarily the
    /// exact position where the character denoted by the property `ch` got typed.
    lsp::Position position{};

    /// The character that has been typed that triggered the formatting on type request. That is not
    /// necessarily the last character that got inserted into the document since the client could
    /// auto insert characters as well (e.g. like automatic brace completion).
    String ch{};

    /// The formatting options.
    lsp::FormattingOptions options{};
};

/// Registration options for a DocumentOnTypeFormattingRequest.
struct DocumentOnTypeFormattingRegistrationOptions : lsp::TextDocumentRegistrationOptions,
                                                     lsp::DocumentOnTypeFormattingOptions {};

/// The parameters of a RenameRequest.
struct RenameParams {
    /// The document to rename.
    lsp::TextDocumentIdentifier text_document{};

    /// The position at which this request was sent.
    lsp::Position position{};

    /// The new name of the symbol. If the given name is not valid the request must return a
    /// ResponseError with an appropriate message set.
    String new_name{};
};

/// Registration options for a RenameRequest.
struct RenameRegistrationOptions : lsp::TextDocumentRegistrationOptions, lsp::RenameOptions {};

/// No documentation available
struct PrepareRenameParams : lsp::TextDocumentPositionParams {};

/// The parameters of a ExecuteCommandRequest.
struct ExecuteCommandParams {
    /// The identifier of the actual command handler.
    String command{};

    /// Arguments that the command should be invoked with.
    Optional<std::vector<lsp::LSPAny>> arguments;
};

/// Registration options for a ExecuteCommandRequest.
struct ExecuteCommandRegistrationOptions : lsp::ExecuteCommandOptions {};

/// The parameters passed via an apply workspace edit request.
struct ApplyWorkspaceEditParams {
    /// An optional label of the workspace edit. This label is presented in the user interface for
    /// example on an undo stack to undo the workspace edit.
    Optional<String> label;

    /// The edits to apply.
    lsp::WorkspaceEdit edit{};
};

/// The result returned from the apply workspace edit request.
///
/// @since 3.17 renamed from ApplyWorkspaceEditResponse
struct ApplyWorkspaceEditResult {
    /// Indicates whether the edit was applied or not.
    Boolean applied{};

    /// An optional textual description for why the edit was not applied. This may be used by the
    /// server for diagnostic logging or to provide a suitable error for a request that triggered
    /// the edit.
    Optional<String> failure_reason;

    /// Depending on the client's failure handling strategy `failedChange` might contain the index
    /// of the change that failed. This property is only available if the client signals a
    /// `failureHandlingStrategy` in its client capabilities.
    Optional<Uinteger> failed_change;
};

/// No documentation available
struct WorkDoneProgressBegin {
    /// The structure type identifier
    static constexpr std::string_view kKind = "begin";

    /// Mandatory title of the progress operation. Used to briefly inform about the kind of
    /// operation being performed. Examples: "Indexing" or "Linking dependencies".
    String title{};

    /// Controls if a cancel button should show to allow the user to cancel the long running
    /// operation. Clients that don't support cancellation are allowed to ignore the setting.
    Optional<Boolean> cancellable;

    /// Optional, more detailed associated progress message. Contains complementary information to
    /// the `title`. Examples: "3/25 files", "project/src/module2", "node_modules/some_dep". If
    /// unset, the previous progress message (if any) is still valid.
    Optional<String> message;

    /// Optional progress percentage to display (value 100 is considered 100%). If not provided
    /// infinite progress is assumed and clients are allowed to ignore the `percentage` value in
    /// subsequent in report notifications. The value should be steadily rising. Clients are free to
    /// ignore values that are not following this rule. The value range is [0, 100].
    Optional<Uinteger> percentage;
};

/// No documentation available
struct WorkDoneProgressReport {
    /// The structure type identifier
    static constexpr std::string_view kKind = "report";

    /// Controls enablement state of a cancel button. Clients that don't support cancellation or
    /// don't support controlling the button's enablement state are allowed to ignore the property.
    Optional<Boolean> cancellable;

    /// Optional, more detailed associated progress message. Contains complementary information to
    /// the `title`. Examples: "3/25 files", "project/src/module2", "node_modules/some_dep". If
    /// unset, the previous progress message (if any) is still valid.
    Optional<String> message;

    /// Optional progress percentage to display (value 100 is considered 100%). If not provided
    /// infinite progress is assumed and clients are allowed to ignore the `percentage` value in
    /// subsequent in report notifications. The value should be steadily rising. Clients are free to
    /// ignore values that are not following this rule. The value range is [0, 100]
    Optional<Uinteger> percentage;
};

/// No documentation available
struct WorkDoneProgressEnd {
    /// The structure type identifier
    static constexpr std::string_view kKind = "end";

    /// Optional, a final message indicating to for example indicate the outcome of the operation.
    Optional<String> message;
};

/// No documentation available
struct SetTraceParams {
    /// No documentation available
    lsp::TraceValues value{};
};

/// No documentation available
struct LogTraceParams {
    /// No documentation available
    String message{};

    /// No documentation available
    Optional<String> verbose;
};

/// No documentation available
struct CancelParams {
    /// The request id to cancel.
    OneOf<Integer, String> id{};
};

/// No documentation available
struct ProgressParams {
    /// The progress token provided by the client or server.
    lsp::ProgressToken token{};

    /// The progress data.
    lsp::LSPAny value{};
};

/// No documentation available
struct WorkDoneProgressParams {
    /// An optional token that a server can use to report work done progress.
    Optional<lsp::ProgressToken> work_done_token;
};

/// No documentation available
struct PartialResultParams {
    /// An optional token that a server can use to report partial results (e.g. streaming) to the
    /// client.
    Optional<lsp::ProgressToken> partial_result_token;
};

/// Represents the connection of two locations. Provides additional metadata over normal Location
/// locations, including an origin range.
struct LocationLink {
    /// Span of the origin of this link. Used as the underlined span for mouse interaction. Defaults
    /// to the word range at the definition position.
    Optional<lsp::Range> origin_selection_range;

    /// The target resource identifier of this link.
    DocumentUri target_uri{};

    /// The full target range of this link. If the target for example is a symbol then target range
    /// is the range enclosing this symbol not including leading/trailing whitespace but everything
    /// else like comments. This information is typically used to highlight the range in the editor.
    lsp::Range target_range{};

    /// The range that should be selected and revealed when this link is being followed, e.g the
    /// name of a function. Must be contained by the `targetRange`. See also `DocumentSymbol#range`
    lsp::Range target_selection_range{};
};

/// Static registration options to be returned in the initialize request.
struct StaticRegistrationOptions {
    /// The id used to register the request. The id can be used to deregister the request again. See
    /// also Registration#id.
    Optional<String> id;
};

/// Provide inline value as text.
///
/// @since 3.17.0
struct InlineValueText {
    /// The document range for which the inline value applies.
    lsp::Range range{};

    /// The text of the inline value.
    String text{};
};

/// Provide inline value through a variable lookup. If only a range is specified, the variable name
/// will be extracted from the underlying document. An optional variable name can be used to
/// override the extracted name.
///
/// @since 3.17.0
struct InlineValueVariableLookup {
    /// The document range for which the inline value applies. The range is used to extract the
    /// variable name from the underlying document.
    lsp::Range range{};

    /// If specified the name of the variable to look up.
    Optional<String> variable_name;

    /// How to perform the lookup.
    Boolean case_sensitive_lookup{};
};

/// Provide an inline value through an expression evaluation. If only a range is specified, the
/// expression will be extracted from the underlying document. An optional expression can be used to
/// override the extracted expression.
///
/// @since 3.17.0
struct InlineValueEvaluatableExpression {
    /// The document range for which the inline value applies. The range is used to extract the
    /// evaluatable expression from the underlying document.
    lsp::Range range{};

    /// If specified the expression overrides the extracted expression.
    Optional<String> expression;
};

/// A full diagnostic report with a set of related documents.
///
/// @since 3.17.0
struct RelatedFullDocumentDiagnosticReport : lsp::FullDocumentDiagnosticReport {
    /// Diagnostics of related documents. This information is useful in programming languages where
    /// code in a file A can generate diagnostics in a file B which A depends on. An example of such
    /// a language is C/C++ where marco definitions in a file a.cpp and result in errors in a header
    /// file b.hpp.
    ///
    /// @since 3.17.0
    Optional<std::unordered_map<
        DocumentUri,
        OneOf<lsp::FullDocumentDiagnosticReport, lsp::UnchangedDocumentDiagnosticReport>>>
        related_documents;
};

/// An unchanged diagnostic report with a set of related documents.
///
/// @since 3.17.0
struct RelatedUnchangedDocumentDiagnosticReport : lsp::UnchangedDocumentDiagnosticReport {
    /// Diagnostics of related documents. This information is useful in programming languages where
    /// code in a file A can generate diagnostics in a file B which A depends on. An example of such
    /// a language is C/C++ where marco definitions in a file a.cpp and result in errors in a header
    /// file b.hpp.
    ///
    /// @since 3.17.0
    Optional<std::unordered_map<
        DocumentUri,
        OneOf<lsp::FullDocumentDiagnosticReport, lsp::UnchangedDocumentDiagnosticReport>>>
        related_documents;
};

/// @since 3.18.0
///
/// Proposed in:
struct PrepareRenamePlaceholder {
    /// No documentation available
    lsp::Range range{};

    /// No documentation available
    String placeholder{};
};

/// @since 3.18.0
///
/// Proposed in:
struct PrepareRenameDefaultBehavior {
    /// No documentation available
    Boolean default_behavior{};
};

/// A full document diagnostic report for a workspace diagnostic result.
///
/// @since 3.17.0
struct WorkspaceFullDocumentDiagnosticReport : lsp::FullDocumentDiagnosticReport {
    /// The URI for which diagnostic information is reported.
    DocumentUri uri{};

    /// The version number for which the diagnostics are reported. If the document is not marked as
    /// open `null` can be provided.
    OneOf<Integer, Null> version{};
};

/// An unchanged document diagnostic report for a workspace diagnostic result.
///
/// @since 3.17.0
struct WorkspaceUnchangedDocumentDiagnosticReport : lsp::UnchangedDocumentDiagnosticReport {
    /// The URI for which diagnostic information is reported.
    DocumentUri uri{};

    /// The version number for which the diagnostics are reported. If the document is not marked as
    /// open `null` can be provided.
    OneOf<Integer, Null> version{};
};

/// @since 3.18.0
///
/// Proposed in:
struct TextDocumentContentChangePartial {
    /// The range of the document that changed.
    lsp::Range range{};

    /// The optional length of the range that got replaced.
    ///
    /// Deprecated: use range instead.
    Optional<Uinteger> range_length;

    /// The new text for the provided range.
    String text{};
};

/// @since 3.18.0
///
/// Proposed in:
struct TextDocumentContentChangeWholeDocument {
    /// The new text of the whole document.
    String text{};
};

/// @since 3.18.0
///
/// Proposed in:
///
/// Deprecated: use MarkupContent instead.
struct MarkedStringWithLanguage {
    /// No documentation available
    String language{};

    /// No documentation available
    String value{};
};

/// A notebook cell text document filter denotes a cell text document by different properties.
///
/// @since 3.17.0
struct NotebookCellTextDocumentFilter {
    /// A filter that matches against the notebook containing the notebook cell. If a string value
    /// is provided it matches against the notebook type. '*' matches every notebook.
    OneOf<String, lsp::NotebookDocumentFilter> notebook{};

    /// A language id like `python`. Will be matched against the language id of the notebook cell
    /// document. '*' matches every language.
    Optional<String> language;
};

/// A relative pattern is a helper to construct glob patterns that are matched relatively to a base
/// URI. The common value for a `baseUri` is a workspace folder root, but it can be another absolute
/// URI as well.
///
/// @since 3.17.0
struct RelativePattern {
    /// A workspace folder or a base URI to which this pattern will be matched against relatively.
    OneOf<lsp::WorkspaceFolder, Uri> base_uri{};

    /// The actual glob pattern;
    lsp::Pattern pattern{};
};

/// A document filter where `language` is required field.
///
/// @since 3.18.0
///
/// Proposed in:
struct TextDocumentFilterLanguage {
    /// A language id, like `typescript`.
    String language{};

    /// A Uri Uri.scheme scheme, like `file` or `untitled`.
    Optional<String> scheme;

    /// A glob pattern, like **​/*.{ts,js}. See TextDocumentFilter for examples.
    Optional<String> pattern;
};

/// A document filter where `scheme` is required field.
///
/// @since 3.18.0
///
/// Proposed in:
struct TextDocumentFilterScheme {
    /// A language id, like `typescript`.
    Optional<String> language;

    /// A Uri Uri.scheme scheme, like `file` or `untitled`.
    String scheme{};

    /// A glob pattern, like **​/*.{ts,js}. See TextDocumentFilter for examples.
    Optional<String> pattern;
};

/// A document filter where `pattern` is required field.
///
/// @since 3.18.0
///
/// Proposed in:
struct TextDocumentFilterPattern {
    /// A language id, like `typescript`.
    Optional<String> language;

    /// A Uri Uri.scheme scheme, like `file` or `untitled`.
    Optional<String> scheme;

    /// A glob pattern, like **​/*.{ts,js}. See TextDocumentFilter for examples.
    String pattern{};
};

/// A notebook document filter where `notebookType` is required field.
///
/// @since 3.18.0
///
/// Proposed in:
struct NotebookDocumentFilterNotebookType {
    /// The type of the enclosing notebook.
    String notebook_type{};

    /// A Uri Uri.scheme scheme, like `file` or `untitled`.
    Optional<String> scheme;

    /// A glob pattern.
    Optional<String> pattern;
};

/// A notebook document filter where `scheme` is required field.
///
/// @since 3.18.0
///
/// Proposed in:
struct NotebookDocumentFilterScheme {
    /// The type of the enclosing notebook.
    Optional<String> notebook_type;

    /// A Uri Uri.scheme scheme, like `file` or `untitled`.
    String scheme{};

    /// A glob pattern.
    Optional<String> pattern;
};

/// A notebook document filter where `pattern` is required field.
///
/// @since 3.18.0
///
/// Proposed in:
struct NotebookDocumentFilterPattern {
    /// The type of the enclosing notebook.
    Optional<String> notebook_type;

    /// A Uri Uri.scheme scheme, like `file` or `untitled`.
    Optional<String> scheme;

    /// A glob pattern.
    String pattern{};
};

////////////////////////////////////////////////////////////////////////////////
// Structure methods
////////////////////////////////////////////////////////////////////////////////

bool operator==(const TextDocumentIdentifier& lhs, const TextDocumentIdentifier& rhs);
bool operator!=(const TextDocumentIdentifier& lhs, const TextDocumentIdentifier& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentIdentifier& out);
Result<const json::Value*> Encode(const TextDocumentIdentifier& in, json::Builder& b);

bool operator==(const Position& lhs, const Position& rhs);
bool operator!=(const Position& lhs, const Position& rhs);
Result<SuccessType> Decode(const json::Value& v, Position& out);
Result<const json::Value*> Encode(const Position& in, json::Builder& b);

bool operator==(const TextDocumentPositionParams& lhs, const TextDocumentPositionParams& rhs);
bool operator!=(const TextDocumentPositionParams& lhs, const TextDocumentPositionParams& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentPositionParams& out);
Result<const json::Value*> Encode(const TextDocumentPositionParams& in, json::Builder& b);

bool operator==(const ImplementationParams& lhs, const ImplementationParams& rhs);
bool operator!=(const ImplementationParams& lhs, const ImplementationParams& rhs);
Result<SuccessType> Decode(const json::Value& v, ImplementationParams& out);
Result<const json::Value*> Encode(const ImplementationParams& in, json::Builder& b);

bool operator==(const Range& lhs, const Range& rhs);
bool operator!=(const Range& lhs, const Range& rhs);
Result<SuccessType> Decode(const json::Value& v, Range& out);
Result<const json::Value*> Encode(const Range& in, json::Builder& b);

bool operator==(const Location& lhs, const Location& rhs);
bool operator!=(const Location& lhs, const Location& rhs);
Result<SuccessType> Decode(const json::Value& v, Location& out);
Result<const json::Value*> Encode(const Location& in, json::Builder& b);

bool operator==(const TextDocumentRegistrationOptions& lhs,
                const TextDocumentRegistrationOptions& rhs);
bool operator!=(const TextDocumentRegistrationOptions& lhs,
                const TextDocumentRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentRegistrationOptions& out);
Result<const json::Value*> Encode(const TextDocumentRegistrationOptions& in, json::Builder& b);

bool operator==(const ImplementationOptions& lhs, const ImplementationOptions& rhs);
bool operator!=(const ImplementationOptions& lhs, const ImplementationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ImplementationOptions& out);
Result<const json::Value*> Encode(const ImplementationOptions& in, json::Builder& b);

bool operator==(const ImplementationRegistrationOptions& lhs,
                const ImplementationRegistrationOptions& rhs);
bool operator!=(const ImplementationRegistrationOptions& lhs,
                const ImplementationRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ImplementationRegistrationOptions& out);
Result<const json::Value*> Encode(const ImplementationRegistrationOptions& in, json::Builder& b);

bool operator==(const TypeDefinitionParams& lhs, const TypeDefinitionParams& rhs);
bool operator!=(const TypeDefinitionParams& lhs, const TypeDefinitionParams& rhs);
Result<SuccessType> Decode(const json::Value& v, TypeDefinitionParams& out);
Result<const json::Value*> Encode(const TypeDefinitionParams& in, json::Builder& b);

bool operator==(const TypeDefinitionOptions& lhs, const TypeDefinitionOptions& rhs);
bool operator!=(const TypeDefinitionOptions& lhs, const TypeDefinitionOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, TypeDefinitionOptions& out);
Result<const json::Value*> Encode(const TypeDefinitionOptions& in, json::Builder& b);

bool operator==(const TypeDefinitionRegistrationOptions& lhs,
                const TypeDefinitionRegistrationOptions& rhs);
bool operator!=(const TypeDefinitionRegistrationOptions& lhs,
                const TypeDefinitionRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, TypeDefinitionRegistrationOptions& out);
Result<const json::Value*> Encode(const TypeDefinitionRegistrationOptions& in, json::Builder& b);

bool operator==(const WorkspaceFolder& lhs, const WorkspaceFolder& rhs);
bool operator!=(const WorkspaceFolder& lhs, const WorkspaceFolder& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceFolder& out);
Result<const json::Value*> Encode(const WorkspaceFolder& in, json::Builder& b);

bool operator==(const WorkspaceFoldersChangeEvent& lhs, const WorkspaceFoldersChangeEvent& rhs);
bool operator!=(const WorkspaceFoldersChangeEvent& lhs, const WorkspaceFoldersChangeEvent& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceFoldersChangeEvent& out);
Result<const json::Value*> Encode(const WorkspaceFoldersChangeEvent& in, json::Builder& b);

bool operator==(const DidChangeWorkspaceFoldersParams& lhs,
                const DidChangeWorkspaceFoldersParams& rhs);
bool operator!=(const DidChangeWorkspaceFoldersParams& lhs,
                const DidChangeWorkspaceFoldersParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DidChangeWorkspaceFoldersParams& out);
Result<const json::Value*> Encode(const DidChangeWorkspaceFoldersParams& in, json::Builder& b);

bool operator==(const ConfigurationItem& lhs, const ConfigurationItem& rhs);
bool operator!=(const ConfigurationItem& lhs, const ConfigurationItem& rhs);
Result<SuccessType> Decode(const json::Value& v, ConfigurationItem& out);
Result<const json::Value*> Encode(const ConfigurationItem& in, json::Builder& b);

bool operator==(const ConfigurationParams& lhs, const ConfigurationParams& rhs);
bool operator!=(const ConfigurationParams& lhs, const ConfigurationParams& rhs);
Result<SuccessType> Decode(const json::Value& v, ConfigurationParams& out);
Result<const json::Value*> Encode(const ConfigurationParams& in, json::Builder& b);

bool operator==(const DocumentColorParams& lhs, const DocumentColorParams& rhs);
bool operator!=(const DocumentColorParams& lhs, const DocumentColorParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentColorParams& out);
Result<const json::Value*> Encode(const DocumentColorParams& in, json::Builder& b);

bool operator==(const Color& lhs, const Color& rhs);
bool operator!=(const Color& lhs, const Color& rhs);
Result<SuccessType> Decode(const json::Value& v, Color& out);
Result<const json::Value*> Encode(const Color& in, json::Builder& b);

bool operator==(const ColorInformation& lhs, const ColorInformation& rhs);
bool operator!=(const ColorInformation& lhs, const ColorInformation& rhs);
Result<SuccessType> Decode(const json::Value& v, ColorInformation& out);
Result<const json::Value*> Encode(const ColorInformation& in, json::Builder& b);

bool operator==(const DocumentColorOptions& lhs, const DocumentColorOptions& rhs);
bool operator!=(const DocumentColorOptions& lhs, const DocumentColorOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentColorOptions& out);
Result<const json::Value*> Encode(const DocumentColorOptions& in, json::Builder& b);

bool operator==(const DocumentColorRegistrationOptions& lhs,
                const DocumentColorRegistrationOptions& rhs);
bool operator!=(const DocumentColorRegistrationOptions& lhs,
                const DocumentColorRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentColorRegistrationOptions& out);
Result<const json::Value*> Encode(const DocumentColorRegistrationOptions& in, json::Builder& b);

bool operator==(const ColorPresentationParams& lhs, const ColorPresentationParams& rhs);
bool operator!=(const ColorPresentationParams& lhs, const ColorPresentationParams& rhs);
Result<SuccessType> Decode(const json::Value& v, ColorPresentationParams& out);
Result<const json::Value*> Encode(const ColorPresentationParams& in, json::Builder& b);

bool operator==(const TextEdit& lhs, const TextEdit& rhs);
bool operator!=(const TextEdit& lhs, const TextEdit& rhs);
Result<SuccessType> Decode(const json::Value& v, TextEdit& out);
Result<const json::Value*> Encode(const TextEdit& in, json::Builder& b);

bool operator==(const ColorPresentation& lhs, const ColorPresentation& rhs);
bool operator!=(const ColorPresentation& lhs, const ColorPresentation& rhs);
Result<SuccessType> Decode(const json::Value& v, ColorPresentation& out);
Result<const json::Value*> Encode(const ColorPresentation& in, json::Builder& b);

bool operator==(const WorkDoneProgressOptions& lhs, const WorkDoneProgressOptions& rhs);
bool operator!=(const WorkDoneProgressOptions& lhs, const WorkDoneProgressOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkDoneProgressOptions& out);
Result<const json::Value*> Encode(const WorkDoneProgressOptions& in, json::Builder& b);

bool operator==(const FoldingRangeParams& lhs, const FoldingRangeParams& rhs);
bool operator!=(const FoldingRangeParams& lhs, const FoldingRangeParams& rhs);
Result<SuccessType> Decode(const json::Value& v, FoldingRangeParams& out);
Result<const json::Value*> Encode(const FoldingRangeParams& in, json::Builder& b);

bool operator==(const FoldingRange& lhs, const FoldingRange& rhs);
bool operator!=(const FoldingRange& lhs, const FoldingRange& rhs);
Result<SuccessType> Decode(const json::Value& v, FoldingRange& out);
Result<const json::Value*> Encode(const FoldingRange& in, json::Builder& b);

bool operator==(const FoldingRangeOptions& lhs, const FoldingRangeOptions& rhs);
bool operator!=(const FoldingRangeOptions& lhs, const FoldingRangeOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, FoldingRangeOptions& out);
Result<const json::Value*> Encode(const FoldingRangeOptions& in, json::Builder& b);

bool operator==(const FoldingRangeRegistrationOptions& lhs,
                const FoldingRangeRegistrationOptions& rhs);
bool operator!=(const FoldingRangeRegistrationOptions& lhs,
                const FoldingRangeRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, FoldingRangeRegistrationOptions& out);
Result<const json::Value*> Encode(const FoldingRangeRegistrationOptions& in, json::Builder& b);

bool operator==(const DeclarationParams& lhs, const DeclarationParams& rhs);
bool operator!=(const DeclarationParams& lhs, const DeclarationParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DeclarationParams& out);
Result<const json::Value*> Encode(const DeclarationParams& in, json::Builder& b);

bool operator==(const DeclarationOptions& lhs, const DeclarationOptions& rhs);
bool operator!=(const DeclarationOptions& lhs, const DeclarationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DeclarationOptions& out);
Result<const json::Value*> Encode(const DeclarationOptions& in, json::Builder& b);

bool operator==(const DeclarationRegistrationOptions& lhs,
                const DeclarationRegistrationOptions& rhs);
bool operator!=(const DeclarationRegistrationOptions& lhs,
                const DeclarationRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DeclarationRegistrationOptions& out);
Result<const json::Value*> Encode(const DeclarationRegistrationOptions& in, json::Builder& b);

bool operator==(const SelectionRangeParams& lhs, const SelectionRangeParams& rhs);
bool operator!=(const SelectionRangeParams& lhs, const SelectionRangeParams& rhs);
Result<SuccessType> Decode(const json::Value& v, SelectionRangeParams& out);
Result<const json::Value*> Encode(const SelectionRangeParams& in, json::Builder& b);

bool operator==(const SelectionRange& lhs, const SelectionRange& rhs);
bool operator!=(const SelectionRange& lhs, const SelectionRange& rhs);
Result<SuccessType> Decode(const json::Value& v, SelectionRange& out);
Result<const json::Value*> Encode(const SelectionRange& in, json::Builder& b);

bool operator==(const SelectionRangeOptions& lhs, const SelectionRangeOptions& rhs);
bool operator!=(const SelectionRangeOptions& lhs, const SelectionRangeOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, SelectionRangeOptions& out);
Result<const json::Value*> Encode(const SelectionRangeOptions& in, json::Builder& b);

bool operator==(const SelectionRangeRegistrationOptions& lhs,
                const SelectionRangeRegistrationOptions& rhs);
bool operator!=(const SelectionRangeRegistrationOptions& lhs,
                const SelectionRangeRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, SelectionRangeRegistrationOptions& out);
Result<const json::Value*> Encode(const SelectionRangeRegistrationOptions& in, json::Builder& b);

bool operator==(const WorkDoneProgressCreateParams& lhs, const WorkDoneProgressCreateParams& rhs);
bool operator!=(const WorkDoneProgressCreateParams& lhs, const WorkDoneProgressCreateParams& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkDoneProgressCreateParams& out);
Result<const json::Value*> Encode(const WorkDoneProgressCreateParams& in, json::Builder& b);

bool operator==(const WorkDoneProgressCancelParams& lhs, const WorkDoneProgressCancelParams& rhs);
bool operator!=(const WorkDoneProgressCancelParams& lhs, const WorkDoneProgressCancelParams& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkDoneProgressCancelParams& out);
Result<const json::Value*> Encode(const WorkDoneProgressCancelParams& in, json::Builder& b);

bool operator==(const CallHierarchyPrepareParams& lhs, const CallHierarchyPrepareParams& rhs);
bool operator!=(const CallHierarchyPrepareParams& lhs, const CallHierarchyPrepareParams& rhs);
Result<SuccessType> Decode(const json::Value& v, CallHierarchyPrepareParams& out);
Result<const json::Value*> Encode(const CallHierarchyPrepareParams& in, json::Builder& b);

bool operator==(const CallHierarchyItem& lhs, const CallHierarchyItem& rhs);
bool operator!=(const CallHierarchyItem& lhs, const CallHierarchyItem& rhs);
Result<SuccessType> Decode(const json::Value& v, CallHierarchyItem& out);
Result<const json::Value*> Encode(const CallHierarchyItem& in, json::Builder& b);

bool operator==(const CallHierarchyOptions& lhs, const CallHierarchyOptions& rhs);
bool operator!=(const CallHierarchyOptions& lhs, const CallHierarchyOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, CallHierarchyOptions& out);
Result<const json::Value*> Encode(const CallHierarchyOptions& in, json::Builder& b);

bool operator==(const CallHierarchyRegistrationOptions& lhs,
                const CallHierarchyRegistrationOptions& rhs);
bool operator!=(const CallHierarchyRegistrationOptions& lhs,
                const CallHierarchyRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, CallHierarchyRegistrationOptions& out);
Result<const json::Value*> Encode(const CallHierarchyRegistrationOptions& in, json::Builder& b);

bool operator==(const CallHierarchyIncomingCallsParams& lhs,
                const CallHierarchyIncomingCallsParams& rhs);
bool operator!=(const CallHierarchyIncomingCallsParams& lhs,
                const CallHierarchyIncomingCallsParams& rhs);
Result<SuccessType> Decode(const json::Value& v, CallHierarchyIncomingCallsParams& out);
Result<const json::Value*> Encode(const CallHierarchyIncomingCallsParams& in, json::Builder& b);

bool operator==(const CallHierarchyIncomingCall& lhs, const CallHierarchyIncomingCall& rhs);
bool operator!=(const CallHierarchyIncomingCall& lhs, const CallHierarchyIncomingCall& rhs);
Result<SuccessType> Decode(const json::Value& v, CallHierarchyIncomingCall& out);
Result<const json::Value*> Encode(const CallHierarchyIncomingCall& in, json::Builder& b);

bool operator==(const CallHierarchyOutgoingCallsParams& lhs,
                const CallHierarchyOutgoingCallsParams& rhs);
bool operator!=(const CallHierarchyOutgoingCallsParams& lhs,
                const CallHierarchyOutgoingCallsParams& rhs);
Result<SuccessType> Decode(const json::Value& v, CallHierarchyOutgoingCallsParams& out);
Result<const json::Value*> Encode(const CallHierarchyOutgoingCallsParams& in, json::Builder& b);

bool operator==(const CallHierarchyOutgoingCall& lhs, const CallHierarchyOutgoingCall& rhs);
bool operator!=(const CallHierarchyOutgoingCall& lhs, const CallHierarchyOutgoingCall& rhs);
Result<SuccessType> Decode(const json::Value& v, CallHierarchyOutgoingCall& out);
Result<const json::Value*> Encode(const CallHierarchyOutgoingCall& in, json::Builder& b);

bool operator==(const SemanticTokensParams& lhs, const SemanticTokensParams& rhs);
bool operator!=(const SemanticTokensParams& lhs, const SemanticTokensParams& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensParams& out);
Result<const json::Value*> Encode(const SemanticTokensParams& in, json::Builder& b);

bool operator==(const SemanticTokens& lhs, const SemanticTokens& rhs);
bool operator!=(const SemanticTokens& lhs, const SemanticTokens& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokens& out);
Result<const json::Value*> Encode(const SemanticTokens& in, json::Builder& b);

bool operator==(const SemanticTokensPartialResult& lhs, const SemanticTokensPartialResult& rhs);
bool operator!=(const SemanticTokensPartialResult& lhs, const SemanticTokensPartialResult& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensPartialResult& out);
Result<const json::Value*> Encode(const SemanticTokensPartialResult& in, json::Builder& b);

bool operator==(const SemanticTokensLegend& lhs, const SemanticTokensLegend& rhs);
bool operator!=(const SemanticTokensLegend& lhs, const SemanticTokensLegend& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensLegend& out);
Result<const json::Value*> Encode(const SemanticTokensLegend& in, json::Builder& b);

bool operator==(const SemanticTokensFullDelta& lhs, const SemanticTokensFullDelta& rhs);
bool operator!=(const SemanticTokensFullDelta& lhs, const SemanticTokensFullDelta& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensFullDelta& out);
Result<const json::Value*> Encode(const SemanticTokensFullDelta& in, json::Builder& b);

bool operator==(const SemanticTokensOptions& lhs, const SemanticTokensOptions& rhs);
bool operator!=(const SemanticTokensOptions& lhs, const SemanticTokensOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensOptions& out);
Result<const json::Value*> Encode(const SemanticTokensOptions& in, json::Builder& b);
bool operator==(const SemanticTokensOptions::Range& lhs, const SemanticTokensOptions::Range& rhs);
bool operator!=(const SemanticTokensOptions::Range& lhs, const SemanticTokensOptions::Range& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensOptions::Range& out);
Result<const json::Value*> Encode(const SemanticTokensOptions::Range& in, json::Builder& b);

bool operator==(const SemanticTokensRegistrationOptions& lhs,
                const SemanticTokensRegistrationOptions& rhs);
bool operator!=(const SemanticTokensRegistrationOptions& lhs,
                const SemanticTokensRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensRegistrationOptions& out);
Result<const json::Value*> Encode(const SemanticTokensRegistrationOptions& in, json::Builder& b);

bool operator==(const SemanticTokensDeltaParams& lhs, const SemanticTokensDeltaParams& rhs);
bool operator!=(const SemanticTokensDeltaParams& lhs, const SemanticTokensDeltaParams& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensDeltaParams& out);
Result<const json::Value*> Encode(const SemanticTokensDeltaParams& in, json::Builder& b);

bool operator==(const SemanticTokensEdit& lhs, const SemanticTokensEdit& rhs);
bool operator!=(const SemanticTokensEdit& lhs, const SemanticTokensEdit& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensEdit& out);
Result<const json::Value*> Encode(const SemanticTokensEdit& in, json::Builder& b);

bool operator==(const SemanticTokensDelta& lhs, const SemanticTokensDelta& rhs);
bool operator!=(const SemanticTokensDelta& lhs, const SemanticTokensDelta& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensDelta& out);
Result<const json::Value*> Encode(const SemanticTokensDelta& in, json::Builder& b);

bool operator==(const SemanticTokensDeltaPartialResult& lhs,
                const SemanticTokensDeltaPartialResult& rhs);
bool operator!=(const SemanticTokensDeltaPartialResult& lhs,
                const SemanticTokensDeltaPartialResult& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensDeltaPartialResult& out);
Result<const json::Value*> Encode(const SemanticTokensDeltaPartialResult& in, json::Builder& b);

bool operator==(const SemanticTokensRangeParams& lhs, const SemanticTokensRangeParams& rhs);
bool operator!=(const SemanticTokensRangeParams& lhs, const SemanticTokensRangeParams& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensRangeParams& out);
Result<const json::Value*> Encode(const SemanticTokensRangeParams& in, json::Builder& b);

bool operator==(const ShowDocumentParams& lhs, const ShowDocumentParams& rhs);
bool operator!=(const ShowDocumentParams& lhs, const ShowDocumentParams& rhs);
Result<SuccessType> Decode(const json::Value& v, ShowDocumentParams& out);
Result<const json::Value*> Encode(const ShowDocumentParams& in, json::Builder& b);

bool operator==(const ShowDocumentResult& lhs, const ShowDocumentResult& rhs);
bool operator!=(const ShowDocumentResult& lhs, const ShowDocumentResult& rhs);
Result<SuccessType> Decode(const json::Value& v, ShowDocumentResult& out);
Result<const json::Value*> Encode(const ShowDocumentResult& in, json::Builder& b);

bool operator==(const LinkedEditingRangeParams& lhs, const LinkedEditingRangeParams& rhs);
bool operator!=(const LinkedEditingRangeParams& lhs, const LinkedEditingRangeParams& rhs);
Result<SuccessType> Decode(const json::Value& v, LinkedEditingRangeParams& out);
Result<const json::Value*> Encode(const LinkedEditingRangeParams& in, json::Builder& b);

bool operator==(const LinkedEditingRanges& lhs, const LinkedEditingRanges& rhs);
bool operator!=(const LinkedEditingRanges& lhs, const LinkedEditingRanges& rhs);
Result<SuccessType> Decode(const json::Value& v, LinkedEditingRanges& out);
Result<const json::Value*> Encode(const LinkedEditingRanges& in, json::Builder& b);

bool operator==(const LinkedEditingRangeOptions& lhs, const LinkedEditingRangeOptions& rhs);
bool operator!=(const LinkedEditingRangeOptions& lhs, const LinkedEditingRangeOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, LinkedEditingRangeOptions& out);
Result<const json::Value*> Encode(const LinkedEditingRangeOptions& in, json::Builder& b);

bool operator==(const LinkedEditingRangeRegistrationOptions& lhs,
                const LinkedEditingRangeRegistrationOptions& rhs);
bool operator!=(const LinkedEditingRangeRegistrationOptions& lhs,
                const LinkedEditingRangeRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, LinkedEditingRangeRegistrationOptions& out);
Result<const json::Value*> Encode(const LinkedEditingRangeRegistrationOptions& in,
                                  json::Builder& b);

bool operator==(const FileCreate& lhs, const FileCreate& rhs);
bool operator!=(const FileCreate& lhs, const FileCreate& rhs);
Result<SuccessType> Decode(const json::Value& v, FileCreate& out);
Result<const json::Value*> Encode(const FileCreate& in, json::Builder& b);

bool operator==(const CreateFilesParams& lhs, const CreateFilesParams& rhs);
bool operator!=(const CreateFilesParams& lhs, const CreateFilesParams& rhs);
Result<SuccessType> Decode(const json::Value& v, CreateFilesParams& out);
Result<const json::Value*> Encode(const CreateFilesParams& in, json::Builder& b);

bool operator==(const ResourceOperation& lhs, const ResourceOperation& rhs);
bool operator!=(const ResourceOperation& lhs, const ResourceOperation& rhs);
Result<SuccessType> Decode(const json::Value& v, ResourceOperation& out);
Result<const json::Value*> Encode(const ResourceOperation& in, json::Builder& b);

bool operator==(const DeleteFileOptions& lhs, const DeleteFileOptions& rhs);
bool operator!=(const DeleteFileOptions& lhs, const DeleteFileOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DeleteFileOptions& out);
Result<const json::Value*> Encode(const DeleteFileOptions& in, json::Builder& b);

bool operator==(const DeleteFile& lhs, const DeleteFile& rhs);
bool operator!=(const DeleteFile& lhs, const DeleteFile& rhs);
Result<SuccessType> Decode(const json::Value& v, DeleteFile& out);
Result<const json::Value*> Encode(const DeleteFile& in, json::Builder& b);

bool operator==(const RenameFileOptions& lhs, const RenameFileOptions& rhs);
bool operator!=(const RenameFileOptions& lhs, const RenameFileOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, RenameFileOptions& out);
Result<const json::Value*> Encode(const RenameFileOptions& in, json::Builder& b);

bool operator==(const RenameFile& lhs, const RenameFile& rhs);
bool operator!=(const RenameFile& lhs, const RenameFile& rhs);
Result<SuccessType> Decode(const json::Value& v, RenameFile& out);
Result<const json::Value*> Encode(const RenameFile& in, json::Builder& b);

bool operator==(const CreateFileOptions& lhs, const CreateFileOptions& rhs);
bool operator!=(const CreateFileOptions& lhs, const CreateFileOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, CreateFileOptions& out);
Result<const json::Value*> Encode(const CreateFileOptions& in, json::Builder& b);

bool operator==(const CreateFile& lhs, const CreateFile& rhs);
bool operator!=(const CreateFile& lhs, const CreateFile& rhs);
Result<SuccessType> Decode(const json::Value& v, CreateFile& out);
Result<const json::Value*> Encode(const CreateFile& in, json::Builder& b);

bool operator==(const OptionalVersionedTextDocumentIdentifier& lhs,
                const OptionalVersionedTextDocumentIdentifier& rhs);
bool operator!=(const OptionalVersionedTextDocumentIdentifier& lhs,
                const OptionalVersionedTextDocumentIdentifier& rhs);
Result<SuccessType> Decode(const json::Value& v, OptionalVersionedTextDocumentIdentifier& out);
Result<const json::Value*> Encode(const OptionalVersionedTextDocumentIdentifier& in,
                                  json::Builder& b);

bool operator==(const AnnotatedTextEdit& lhs, const AnnotatedTextEdit& rhs);
bool operator!=(const AnnotatedTextEdit& lhs, const AnnotatedTextEdit& rhs);
Result<SuccessType> Decode(const json::Value& v, AnnotatedTextEdit& out);
Result<const json::Value*> Encode(const AnnotatedTextEdit& in, json::Builder& b);

bool operator==(const TextDocumentEdit& lhs, const TextDocumentEdit& rhs);
bool operator!=(const TextDocumentEdit& lhs, const TextDocumentEdit& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentEdit& out);
Result<const json::Value*> Encode(const TextDocumentEdit& in, json::Builder& b);

bool operator==(const ChangeAnnotation& lhs, const ChangeAnnotation& rhs);
bool operator!=(const ChangeAnnotation& lhs, const ChangeAnnotation& rhs);
Result<SuccessType> Decode(const json::Value& v, ChangeAnnotation& out);
Result<const json::Value*> Encode(const ChangeAnnotation& in, json::Builder& b);

bool operator==(const WorkspaceEdit& lhs, const WorkspaceEdit& rhs);
bool operator!=(const WorkspaceEdit& lhs, const WorkspaceEdit& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceEdit& out);
Result<const json::Value*> Encode(const WorkspaceEdit& in, json::Builder& b);

bool operator==(const FileOperationPatternOptions& lhs, const FileOperationPatternOptions& rhs);
bool operator!=(const FileOperationPatternOptions& lhs, const FileOperationPatternOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, FileOperationPatternOptions& out);
Result<const json::Value*> Encode(const FileOperationPatternOptions& in, json::Builder& b);

bool operator==(const FileOperationPattern& lhs, const FileOperationPattern& rhs);
bool operator!=(const FileOperationPattern& lhs, const FileOperationPattern& rhs);
Result<SuccessType> Decode(const json::Value& v, FileOperationPattern& out);
Result<const json::Value*> Encode(const FileOperationPattern& in, json::Builder& b);

bool operator==(const FileOperationFilter& lhs, const FileOperationFilter& rhs);
bool operator!=(const FileOperationFilter& lhs, const FileOperationFilter& rhs);
Result<SuccessType> Decode(const json::Value& v, FileOperationFilter& out);
Result<const json::Value*> Encode(const FileOperationFilter& in, json::Builder& b);

bool operator==(const FileOperationRegistrationOptions& lhs,
                const FileOperationRegistrationOptions& rhs);
bool operator!=(const FileOperationRegistrationOptions& lhs,
                const FileOperationRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, FileOperationRegistrationOptions& out);
Result<const json::Value*> Encode(const FileOperationRegistrationOptions& in, json::Builder& b);

bool operator==(const FileRename& lhs, const FileRename& rhs);
bool operator!=(const FileRename& lhs, const FileRename& rhs);
Result<SuccessType> Decode(const json::Value& v, FileRename& out);
Result<const json::Value*> Encode(const FileRename& in, json::Builder& b);

bool operator==(const RenameFilesParams& lhs, const RenameFilesParams& rhs);
bool operator!=(const RenameFilesParams& lhs, const RenameFilesParams& rhs);
Result<SuccessType> Decode(const json::Value& v, RenameFilesParams& out);
Result<const json::Value*> Encode(const RenameFilesParams& in, json::Builder& b);

bool operator==(const FileDelete& lhs, const FileDelete& rhs);
bool operator!=(const FileDelete& lhs, const FileDelete& rhs);
Result<SuccessType> Decode(const json::Value& v, FileDelete& out);
Result<const json::Value*> Encode(const FileDelete& in, json::Builder& b);

bool operator==(const DeleteFilesParams& lhs, const DeleteFilesParams& rhs);
bool operator!=(const DeleteFilesParams& lhs, const DeleteFilesParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DeleteFilesParams& out);
Result<const json::Value*> Encode(const DeleteFilesParams& in, json::Builder& b);

bool operator==(const MonikerParams& lhs, const MonikerParams& rhs);
bool operator!=(const MonikerParams& lhs, const MonikerParams& rhs);
Result<SuccessType> Decode(const json::Value& v, MonikerParams& out);
Result<const json::Value*> Encode(const MonikerParams& in, json::Builder& b);

bool operator==(const Moniker& lhs, const Moniker& rhs);
bool operator!=(const Moniker& lhs, const Moniker& rhs);
Result<SuccessType> Decode(const json::Value& v, Moniker& out);
Result<const json::Value*> Encode(const Moniker& in, json::Builder& b);

bool operator==(const MonikerOptions& lhs, const MonikerOptions& rhs);
bool operator!=(const MonikerOptions& lhs, const MonikerOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, MonikerOptions& out);
Result<const json::Value*> Encode(const MonikerOptions& in, json::Builder& b);

bool operator==(const MonikerRegistrationOptions& lhs, const MonikerRegistrationOptions& rhs);
bool operator!=(const MonikerRegistrationOptions& lhs, const MonikerRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, MonikerRegistrationOptions& out);
Result<const json::Value*> Encode(const MonikerRegistrationOptions& in, json::Builder& b);

bool operator==(const TypeHierarchyPrepareParams& lhs, const TypeHierarchyPrepareParams& rhs);
bool operator!=(const TypeHierarchyPrepareParams& lhs, const TypeHierarchyPrepareParams& rhs);
Result<SuccessType> Decode(const json::Value& v, TypeHierarchyPrepareParams& out);
Result<const json::Value*> Encode(const TypeHierarchyPrepareParams& in, json::Builder& b);

bool operator==(const TypeHierarchyItem& lhs, const TypeHierarchyItem& rhs);
bool operator!=(const TypeHierarchyItem& lhs, const TypeHierarchyItem& rhs);
Result<SuccessType> Decode(const json::Value& v, TypeHierarchyItem& out);
Result<const json::Value*> Encode(const TypeHierarchyItem& in, json::Builder& b);

bool operator==(const TypeHierarchyOptions& lhs, const TypeHierarchyOptions& rhs);
bool operator!=(const TypeHierarchyOptions& lhs, const TypeHierarchyOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, TypeHierarchyOptions& out);
Result<const json::Value*> Encode(const TypeHierarchyOptions& in, json::Builder& b);

bool operator==(const TypeHierarchyRegistrationOptions& lhs,
                const TypeHierarchyRegistrationOptions& rhs);
bool operator!=(const TypeHierarchyRegistrationOptions& lhs,
                const TypeHierarchyRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, TypeHierarchyRegistrationOptions& out);
Result<const json::Value*> Encode(const TypeHierarchyRegistrationOptions& in, json::Builder& b);

bool operator==(const TypeHierarchySupertypesParams& lhs, const TypeHierarchySupertypesParams& rhs);
bool operator!=(const TypeHierarchySupertypesParams& lhs, const TypeHierarchySupertypesParams& rhs);
Result<SuccessType> Decode(const json::Value& v, TypeHierarchySupertypesParams& out);
Result<const json::Value*> Encode(const TypeHierarchySupertypesParams& in, json::Builder& b);

bool operator==(const TypeHierarchySubtypesParams& lhs, const TypeHierarchySubtypesParams& rhs);
bool operator!=(const TypeHierarchySubtypesParams& lhs, const TypeHierarchySubtypesParams& rhs);
Result<SuccessType> Decode(const json::Value& v, TypeHierarchySubtypesParams& out);
Result<const json::Value*> Encode(const TypeHierarchySubtypesParams& in, json::Builder& b);

bool operator==(const InlineValueContext& lhs, const InlineValueContext& rhs);
bool operator!=(const InlineValueContext& lhs, const InlineValueContext& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineValueContext& out);
Result<const json::Value*> Encode(const InlineValueContext& in, json::Builder& b);

bool operator==(const InlineValueParams& lhs, const InlineValueParams& rhs);
bool operator!=(const InlineValueParams& lhs, const InlineValueParams& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineValueParams& out);
Result<const json::Value*> Encode(const InlineValueParams& in, json::Builder& b);

bool operator==(const InlineValueOptions& lhs, const InlineValueOptions& rhs);
bool operator!=(const InlineValueOptions& lhs, const InlineValueOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineValueOptions& out);
Result<const json::Value*> Encode(const InlineValueOptions& in, json::Builder& b);

bool operator==(const InlineValueRegistrationOptions& lhs,
                const InlineValueRegistrationOptions& rhs);
bool operator!=(const InlineValueRegistrationOptions& lhs,
                const InlineValueRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineValueRegistrationOptions& out);
Result<const json::Value*> Encode(const InlineValueRegistrationOptions& in, json::Builder& b);

bool operator==(const InlayHintParams& lhs, const InlayHintParams& rhs);
bool operator!=(const InlayHintParams& lhs, const InlayHintParams& rhs);
Result<SuccessType> Decode(const json::Value& v, InlayHintParams& out);
Result<const json::Value*> Encode(const InlayHintParams& in, json::Builder& b);

bool operator==(const MarkupContent& lhs, const MarkupContent& rhs);
bool operator!=(const MarkupContent& lhs, const MarkupContent& rhs);
Result<SuccessType> Decode(const json::Value& v, MarkupContent& out);
Result<const json::Value*> Encode(const MarkupContent& in, json::Builder& b);

bool operator==(const Command& lhs, const Command& rhs);
bool operator!=(const Command& lhs, const Command& rhs);
Result<SuccessType> Decode(const json::Value& v, Command& out);
Result<const json::Value*> Encode(const Command& in, json::Builder& b);

bool operator==(const InlayHintLabelPart& lhs, const InlayHintLabelPart& rhs);
bool operator!=(const InlayHintLabelPart& lhs, const InlayHintLabelPart& rhs);
Result<SuccessType> Decode(const json::Value& v, InlayHintLabelPart& out);
Result<const json::Value*> Encode(const InlayHintLabelPart& in, json::Builder& b);

bool operator==(const InlayHint& lhs, const InlayHint& rhs);
bool operator!=(const InlayHint& lhs, const InlayHint& rhs);
Result<SuccessType> Decode(const json::Value& v, InlayHint& out);
Result<const json::Value*> Encode(const InlayHint& in, json::Builder& b);

bool operator==(const InlayHintOptions& lhs, const InlayHintOptions& rhs);
bool operator!=(const InlayHintOptions& lhs, const InlayHintOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, InlayHintOptions& out);
Result<const json::Value*> Encode(const InlayHintOptions& in, json::Builder& b);

bool operator==(const InlayHintRegistrationOptions& lhs, const InlayHintRegistrationOptions& rhs);
bool operator!=(const InlayHintRegistrationOptions& lhs, const InlayHintRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, InlayHintRegistrationOptions& out);
Result<const json::Value*> Encode(const InlayHintRegistrationOptions& in, json::Builder& b);

bool operator==(const DocumentDiagnosticParams& lhs, const DocumentDiagnosticParams& rhs);
bool operator!=(const DocumentDiagnosticParams& lhs, const DocumentDiagnosticParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentDiagnosticParams& out);
Result<const json::Value*> Encode(const DocumentDiagnosticParams& in, json::Builder& b);

bool operator==(const UnchangedDocumentDiagnosticReport& lhs,
                const UnchangedDocumentDiagnosticReport& rhs);
bool operator!=(const UnchangedDocumentDiagnosticReport& lhs,
                const UnchangedDocumentDiagnosticReport& rhs);
Result<SuccessType> Decode(const json::Value& v, UnchangedDocumentDiagnosticReport& out);
Result<const json::Value*> Encode(const UnchangedDocumentDiagnosticReport& in, json::Builder& b);

bool operator==(const CodeDescription& lhs, const CodeDescription& rhs);
bool operator!=(const CodeDescription& lhs, const CodeDescription& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeDescription& out);
Result<const json::Value*> Encode(const CodeDescription& in, json::Builder& b);

bool operator==(const DiagnosticRelatedInformation& lhs, const DiagnosticRelatedInformation& rhs);
bool operator!=(const DiagnosticRelatedInformation& lhs, const DiagnosticRelatedInformation& rhs);
Result<SuccessType> Decode(const json::Value& v, DiagnosticRelatedInformation& out);
Result<const json::Value*> Encode(const DiagnosticRelatedInformation& in, json::Builder& b);

bool operator==(const Diagnostic& lhs, const Diagnostic& rhs);
bool operator!=(const Diagnostic& lhs, const Diagnostic& rhs);
Result<SuccessType> Decode(const json::Value& v, Diagnostic& out);
Result<const json::Value*> Encode(const Diagnostic& in, json::Builder& b);

bool operator==(const FullDocumentDiagnosticReport& lhs, const FullDocumentDiagnosticReport& rhs);
bool operator!=(const FullDocumentDiagnosticReport& lhs, const FullDocumentDiagnosticReport& rhs);
Result<SuccessType> Decode(const json::Value& v, FullDocumentDiagnosticReport& out);
Result<const json::Value*> Encode(const FullDocumentDiagnosticReport& in, json::Builder& b);

bool operator==(const DocumentDiagnosticReportPartialResult& lhs,
                const DocumentDiagnosticReportPartialResult& rhs);
bool operator!=(const DocumentDiagnosticReportPartialResult& lhs,
                const DocumentDiagnosticReportPartialResult& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentDiagnosticReportPartialResult& out);
Result<const json::Value*> Encode(const DocumentDiagnosticReportPartialResult& in,
                                  json::Builder& b);

bool operator==(const DiagnosticServerCancellationData& lhs,
                const DiagnosticServerCancellationData& rhs);
bool operator!=(const DiagnosticServerCancellationData& lhs,
                const DiagnosticServerCancellationData& rhs);
Result<SuccessType> Decode(const json::Value& v, DiagnosticServerCancellationData& out);
Result<const json::Value*> Encode(const DiagnosticServerCancellationData& in, json::Builder& b);

bool operator==(const DiagnosticOptions& lhs, const DiagnosticOptions& rhs);
bool operator!=(const DiagnosticOptions& lhs, const DiagnosticOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DiagnosticOptions& out);
Result<const json::Value*> Encode(const DiagnosticOptions& in, json::Builder& b);

bool operator==(const DiagnosticRegistrationOptions& lhs, const DiagnosticRegistrationOptions& rhs);
bool operator!=(const DiagnosticRegistrationOptions& lhs, const DiagnosticRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DiagnosticRegistrationOptions& out);
Result<const json::Value*> Encode(const DiagnosticRegistrationOptions& in, json::Builder& b);

bool operator==(const PreviousResultId& lhs, const PreviousResultId& rhs);
bool operator!=(const PreviousResultId& lhs, const PreviousResultId& rhs);
Result<SuccessType> Decode(const json::Value& v, PreviousResultId& out);
Result<const json::Value*> Encode(const PreviousResultId& in, json::Builder& b);

bool operator==(const WorkspaceDiagnosticParams& lhs, const WorkspaceDiagnosticParams& rhs);
bool operator!=(const WorkspaceDiagnosticParams& lhs, const WorkspaceDiagnosticParams& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceDiagnosticParams& out);
Result<const json::Value*> Encode(const WorkspaceDiagnosticParams& in, json::Builder& b);

bool operator==(const WorkspaceDiagnosticReport& lhs, const WorkspaceDiagnosticReport& rhs);
bool operator!=(const WorkspaceDiagnosticReport& lhs, const WorkspaceDiagnosticReport& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceDiagnosticReport& out);
Result<const json::Value*> Encode(const WorkspaceDiagnosticReport& in, json::Builder& b);

bool operator==(const WorkspaceDiagnosticReportPartialResult& lhs,
                const WorkspaceDiagnosticReportPartialResult& rhs);
bool operator!=(const WorkspaceDiagnosticReportPartialResult& lhs,
                const WorkspaceDiagnosticReportPartialResult& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceDiagnosticReportPartialResult& out);
Result<const json::Value*> Encode(const WorkspaceDiagnosticReportPartialResult& in,
                                  json::Builder& b);

bool operator==(const ExecutionSummary& lhs, const ExecutionSummary& rhs);
bool operator!=(const ExecutionSummary& lhs, const ExecutionSummary& rhs);
Result<SuccessType> Decode(const json::Value& v, ExecutionSummary& out);
Result<const json::Value*> Encode(const ExecutionSummary& in, json::Builder& b);

bool operator==(const NotebookCell& lhs, const NotebookCell& rhs);
bool operator!=(const NotebookCell& lhs, const NotebookCell& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookCell& out);
Result<const json::Value*> Encode(const NotebookCell& in, json::Builder& b);

bool operator==(const NotebookDocument& lhs, const NotebookDocument& rhs);
bool operator!=(const NotebookDocument& lhs, const NotebookDocument& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocument& out);
Result<const json::Value*> Encode(const NotebookDocument& in, json::Builder& b);

bool operator==(const TextDocumentItem& lhs, const TextDocumentItem& rhs);
bool operator!=(const TextDocumentItem& lhs, const TextDocumentItem& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentItem& out);
Result<const json::Value*> Encode(const TextDocumentItem& in, json::Builder& b);

bool operator==(const DidOpenNotebookDocumentParams& lhs, const DidOpenNotebookDocumentParams& rhs);
bool operator!=(const DidOpenNotebookDocumentParams& lhs, const DidOpenNotebookDocumentParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DidOpenNotebookDocumentParams& out);
Result<const json::Value*> Encode(const DidOpenNotebookDocumentParams& in, json::Builder& b);

bool operator==(const VersionedNotebookDocumentIdentifier& lhs,
                const VersionedNotebookDocumentIdentifier& rhs);
bool operator!=(const VersionedNotebookDocumentIdentifier& lhs,
                const VersionedNotebookDocumentIdentifier& rhs);
Result<SuccessType> Decode(const json::Value& v, VersionedNotebookDocumentIdentifier& out);
Result<const json::Value*> Encode(const VersionedNotebookDocumentIdentifier& in, json::Builder& b);

bool operator==(const NotebookCellArrayChange& lhs, const NotebookCellArrayChange& rhs);
bool operator!=(const NotebookCellArrayChange& lhs, const NotebookCellArrayChange& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookCellArrayChange& out);
Result<const json::Value*> Encode(const NotebookCellArrayChange& in, json::Builder& b);

bool operator==(const NotebookDocumentCellChangeStructure& lhs,
                const NotebookDocumentCellChangeStructure& rhs);
bool operator!=(const NotebookDocumentCellChangeStructure& lhs,
                const NotebookDocumentCellChangeStructure& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentCellChangeStructure& out);
Result<const json::Value*> Encode(const NotebookDocumentCellChangeStructure& in, json::Builder& b);

bool operator==(const VersionedTextDocumentIdentifier& lhs,
                const VersionedTextDocumentIdentifier& rhs);
bool operator!=(const VersionedTextDocumentIdentifier& lhs,
                const VersionedTextDocumentIdentifier& rhs);
Result<SuccessType> Decode(const json::Value& v, VersionedTextDocumentIdentifier& out);
Result<const json::Value*> Encode(const VersionedTextDocumentIdentifier& in, json::Builder& b);

bool operator==(const NotebookDocumentCellContentChanges& lhs,
                const NotebookDocumentCellContentChanges& rhs);
bool operator!=(const NotebookDocumentCellContentChanges& lhs,
                const NotebookDocumentCellContentChanges& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentCellContentChanges& out);
Result<const json::Value*> Encode(const NotebookDocumentCellContentChanges& in, json::Builder& b);

bool operator==(const NotebookDocumentCellChanges& lhs, const NotebookDocumentCellChanges& rhs);
bool operator!=(const NotebookDocumentCellChanges& lhs, const NotebookDocumentCellChanges& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentCellChanges& out);
Result<const json::Value*> Encode(const NotebookDocumentCellChanges& in, json::Builder& b);

bool operator==(const NotebookDocumentChangeEvent& lhs, const NotebookDocumentChangeEvent& rhs);
bool operator!=(const NotebookDocumentChangeEvent& lhs, const NotebookDocumentChangeEvent& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentChangeEvent& out);
Result<const json::Value*> Encode(const NotebookDocumentChangeEvent& in, json::Builder& b);

bool operator==(const DidChangeNotebookDocumentParams& lhs,
                const DidChangeNotebookDocumentParams& rhs);
bool operator!=(const DidChangeNotebookDocumentParams& lhs,
                const DidChangeNotebookDocumentParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DidChangeNotebookDocumentParams& out);
Result<const json::Value*> Encode(const DidChangeNotebookDocumentParams& in, json::Builder& b);

bool operator==(const NotebookDocumentIdentifier& lhs, const NotebookDocumentIdentifier& rhs);
bool operator!=(const NotebookDocumentIdentifier& lhs, const NotebookDocumentIdentifier& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentIdentifier& out);
Result<const json::Value*> Encode(const NotebookDocumentIdentifier& in, json::Builder& b);

bool operator==(const DidSaveNotebookDocumentParams& lhs, const DidSaveNotebookDocumentParams& rhs);
bool operator!=(const DidSaveNotebookDocumentParams& lhs, const DidSaveNotebookDocumentParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DidSaveNotebookDocumentParams& out);
Result<const json::Value*> Encode(const DidSaveNotebookDocumentParams& in, json::Builder& b);

bool operator==(const DidCloseNotebookDocumentParams& lhs,
                const DidCloseNotebookDocumentParams& rhs);
bool operator!=(const DidCloseNotebookDocumentParams& lhs,
                const DidCloseNotebookDocumentParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DidCloseNotebookDocumentParams& out);
Result<const json::Value*> Encode(const DidCloseNotebookDocumentParams& in, json::Builder& b);

bool operator==(const SelectedCompletionInfo& lhs, const SelectedCompletionInfo& rhs);
bool operator!=(const SelectedCompletionInfo& lhs, const SelectedCompletionInfo& rhs);
Result<SuccessType> Decode(const json::Value& v, SelectedCompletionInfo& out);
Result<const json::Value*> Encode(const SelectedCompletionInfo& in, json::Builder& b);

bool operator==(const InlineCompletionContext& lhs, const InlineCompletionContext& rhs);
bool operator!=(const InlineCompletionContext& lhs, const InlineCompletionContext& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineCompletionContext& out);
Result<const json::Value*> Encode(const InlineCompletionContext& in, json::Builder& b);

bool operator==(const InlineCompletionParams& lhs, const InlineCompletionParams& rhs);
bool operator!=(const InlineCompletionParams& lhs, const InlineCompletionParams& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineCompletionParams& out);
Result<const json::Value*> Encode(const InlineCompletionParams& in, json::Builder& b);

bool operator==(const StringValue& lhs, const StringValue& rhs);
bool operator!=(const StringValue& lhs, const StringValue& rhs);
Result<SuccessType> Decode(const json::Value& v, StringValue& out);
Result<const json::Value*> Encode(const StringValue& in, json::Builder& b);

bool operator==(const InlineCompletionItem& lhs, const InlineCompletionItem& rhs);
bool operator!=(const InlineCompletionItem& lhs, const InlineCompletionItem& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineCompletionItem& out);
Result<const json::Value*> Encode(const InlineCompletionItem& in, json::Builder& b);

bool operator==(const InlineCompletionList& lhs, const InlineCompletionList& rhs);
bool operator!=(const InlineCompletionList& lhs, const InlineCompletionList& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineCompletionList& out);
Result<const json::Value*> Encode(const InlineCompletionList& in, json::Builder& b);

bool operator==(const InlineCompletionOptions& lhs, const InlineCompletionOptions& rhs);
bool operator!=(const InlineCompletionOptions& lhs, const InlineCompletionOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineCompletionOptions& out);
Result<const json::Value*> Encode(const InlineCompletionOptions& in, json::Builder& b);

bool operator==(const InlineCompletionRegistrationOptions& lhs,
                const InlineCompletionRegistrationOptions& rhs);
bool operator!=(const InlineCompletionRegistrationOptions& lhs,
                const InlineCompletionRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineCompletionRegistrationOptions& out);
Result<const json::Value*> Encode(const InlineCompletionRegistrationOptions& in, json::Builder& b);

bool operator==(const Registration& lhs, const Registration& rhs);
bool operator!=(const Registration& lhs, const Registration& rhs);
Result<SuccessType> Decode(const json::Value& v, Registration& out);
Result<const json::Value*> Encode(const Registration& in, json::Builder& b);

bool operator==(const RegistrationParams& lhs, const RegistrationParams& rhs);
bool operator!=(const RegistrationParams& lhs, const RegistrationParams& rhs);
Result<SuccessType> Decode(const json::Value& v, RegistrationParams& out);
Result<const json::Value*> Encode(const RegistrationParams& in, json::Builder& b);

bool operator==(const Unregistration& lhs, const Unregistration& rhs);
bool operator!=(const Unregistration& lhs, const Unregistration& rhs);
Result<SuccessType> Decode(const json::Value& v, Unregistration& out);
Result<const json::Value*> Encode(const Unregistration& in, json::Builder& b);

bool operator==(const UnregistrationParams& lhs, const UnregistrationParams& rhs);
bool operator!=(const UnregistrationParams& lhs, const UnregistrationParams& rhs);
Result<SuccessType> Decode(const json::Value& v, UnregistrationParams& out);
Result<const json::Value*> Encode(const UnregistrationParams& in, json::Builder& b);

bool operator==(const ClientInfo& lhs, const ClientInfo& rhs);
bool operator!=(const ClientInfo& lhs, const ClientInfo& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientInfo& out);
Result<const json::Value*> Encode(const ClientInfo& in, json::Builder& b);

bool operator==(const ChangeAnnotationsSupportOptions& lhs,
                const ChangeAnnotationsSupportOptions& rhs);
bool operator!=(const ChangeAnnotationsSupportOptions& lhs,
                const ChangeAnnotationsSupportOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ChangeAnnotationsSupportOptions& out);
Result<const json::Value*> Encode(const ChangeAnnotationsSupportOptions& in, json::Builder& b);

bool operator==(const WorkspaceEditClientCapabilities& lhs,
                const WorkspaceEditClientCapabilities& rhs);
bool operator!=(const WorkspaceEditClientCapabilities& lhs,
                const WorkspaceEditClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceEditClientCapabilities& out);
Result<const json::Value*> Encode(const WorkspaceEditClientCapabilities& in, json::Builder& b);

bool operator==(const DidChangeConfigurationClientCapabilities& lhs,
                const DidChangeConfigurationClientCapabilities& rhs);
bool operator!=(const DidChangeConfigurationClientCapabilities& lhs,
                const DidChangeConfigurationClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, DidChangeConfigurationClientCapabilities& out);
Result<const json::Value*> Encode(const DidChangeConfigurationClientCapabilities& in,
                                  json::Builder& b);

bool operator==(const DidChangeWatchedFilesClientCapabilities& lhs,
                const DidChangeWatchedFilesClientCapabilities& rhs);
bool operator!=(const DidChangeWatchedFilesClientCapabilities& lhs,
                const DidChangeWatchedFilesClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, DidChangeWatchedFilesClientCapabilities& out);
Result<const json::Value*> Encode(const DidChangeWatchedFilesClientCapabilities& in,
                                  json::Builder& b);

bool operator==(const ClientSymbolKindOptions& lhs, const ClientSymbolKindOptions& rhs);
bool operator!=(const ClientSymbolKindOptions& lhs, const ClientSymbolKindOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientSymbolKindOptions& out);
Result<const json::Value*> Encode(const ClientSymbolKindOptions& in, json::Builder& b);

bool operator==(const ClientSymbolTagOptions& lhs, const ClientSymbolTagOptions& rhs);
bool operator!=(const ClientSymbolTagOptions& lhs, const ClientSymbolTagOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientSymbolTagOptions& out);
Result<const json::Value*> Encode(const ClientSymbolTagOptions& in, json::Builder& b);

bool operator==(const ClientSymbolResolveOptions& lhs, const ClientSymbolResolveOptions& rhs);
bool operator!=(const ClientSymbolResolveOptions& lhs, const ClientSymbolResolveOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientSymbolResolveOptions& out);
Result<const json::Value*> Encode(const ClientSymbolResolveOptions& in, json::Builder& b);

bool operator==(const WorkspaceSymbolClientCapabilities& lhs,
                const WorkspaceSymbolClientCapabilities& rhs);
bool operator!=(const WorkspaceSymbolClientCapabilities& lhs,
                const WorkspaceSymbolClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceSymbolClientCapabilities& out);
Result<const json::Value*> Encode(const WorkspaceSymbolClientCapabilities& in, json::Builder& b);

bool operator==(const ExecuteCommandClientCapabilities& lhs,
                const ExecuteCommandClientCapabilities& rhs);
bool operator!=(const ExecuteCommandClientCapabilities& lhs,
                const ExecuteCommandClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, ExecuteCommandClientCapabilities& out);
Result<const json::Value*> Encode(const ExecuteCommandClientCapabilities& in, json::Builder& b);

bool operator==(const SemanticTokensWorkspaceClientCapabilities& lhs,
                const SemanticTokensWorkspaceClientCapabilities& rhs);
bool operator!=(const SemanticTokensWorkspaceClientCapabilities& lhs,
                const SemanticTokensWorkspaceClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensWorkspaceClientCapabilities& out);
Result<const json::Value*> Encode(const SemanticTokensWorkspaceClientCapabilities& in,
                                  json::Builder& b);

bool operator==(const CodeLensWorkspaceClientCapabilities& lhs,
                const CodeLensWorkspaceClientCapabilities& rhs);
bool operator!=(const CodeLensWorkspaceClientCapabilities& lhs,
                const CodeLensWorkspaceClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeLensWorkspaceClientCapabilities& out);
Result<const json::Value*> Encode(const CodeLensWorkspaceClientCapabilities& in, json::Builder& b);

bool operator==(const FileOperationClientCapabilities& lhs,
                const FileOperationClientCapabilities& rhs);
bool operator!=(const FileOperationClientCapabilities& lhs,
                const FileOperationClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, FileOperationClientCapabilities& out);
Result<const json::Value*> Encode(const FileOperationClientCapabilities& in, json::Builder& b);

bool operator==(const InlineValueWorkspaceClientCapabilities& lhs,
                const InlineValueWorkspaceClientCapabilities& rhs);
bool operator!=(const InlineValueWorkspaceClientCapabilities& lhs,
                const InlineValueWorkspaceClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineValueWorkspaceClientCapabilities& out);
Result<const json::Value*> Encode(const InlineValueWorkspaceClientCapabilities& in,
                                  json::Builder& b);

bool operator==(const InlayHintWorkspaceClientCapabilities& lhs,
                const InlayHintWorkspaceClientCapabilities& rhs);
bool operator!=(const InlayHintWorkspaceClientCapabilities& lhs,
                const InlayHintWorkspaceClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, InlayHintWorkspaceClientCapabilities& out);
Result<const json::Value*> Encode(const InlayHintWorkspaceClientCapabilities& in, json::Builder& b);

bool operator==(const DiagnosticWorkspaceClientCapabilities& lhs,
                const DiagnosticWorkspaceClientCapabilities& rhs);
bool operator!=(const DiagnosticWorkspaceClientCapabilities& lhs,
                const DiagnosticWorkspaceClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, DiagnosticWorkspaceClientCapabilities& out);
Result<const json::Value*> Encode(const DiagnosticWorkspaceClientCapabilities& in,
                                  json::Builder& b);

bool operator==(const FoldingRangeWorkspaceClientCapabilities& lhs,
                const FoldingRangeWorkspaceClientCapabilities& rhs);
bool operator!=(const FoldingRangeWorkspaceClientCapabilities& lhs,
                const FoldingRangeWorkspaceClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, FoldingRangeWorkspaceClientCapabilities& out);
Result<const json::Value*> Encode(const FoldingRangeWorkspaceClientCapabilities& in,
                                  json::Builder& b);

bool operator==(const WorkspaceClientCapabilities& lhs, const WorkspaceClientCapabilities& rhs);
bool operator!=(const WorkspaceClientCapabilities& lhs, const WorkspaceClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceClientCapabilities& out);
Result<const json::Value*> Encode(const WorkspaceClientCapabilities& in, json::Builder& b);

bool operator==(const TextDocumentSyncClientCapabilities& lhs,
                const TextDocumentSyncClientCapabilities& rhs);
bool operator!=(const TextDocumentSyncClientCapabilities& lhs,
                const TextDocumentSyncClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentSyncClientCapabilities& out);
Result<const json::Value*> Encode(const TextDocumentSyncClientCapabilities& in, json::Builder& b);

bool operator==(const CompletionItemTagOptions& lhs, const CompletionItemTagOptions& rhs);
bool operator!=(const CompletionItemTagOptions& lhs, const CompletionItemTagOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, CompletionItemTagOptions& out);
Result<const json::Value*> Encode(const CompletionItemTagOptions& in, json::Builder& b);

bool operator==(const ClientCompletionItemResolveOptions& lhs,
                const ClientCompletionItemResolveOptions& rhs);
bool operator!=(const ClientCompletionItemResolveOptions& lhs,
                const ClientCompletionItemResolveOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientCompletionItemResolveOptions& out);
Result<const json::Value*> Encode(const ClientCompletionItemResolveOptions& in, json::Builder& b);

bool operator==(const ClientCompletionItemInsertTextModeOptions& lhs,
                const ClientCompletionItemInsertTextModeOptions& rhs);
bool operator!=(const ClientCompletionItemInsertTextModeOptions& lhs,
                const ClientCompletionItemInsertTextModeOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientCompletionItemInsertTextModeOptions& out);
Result<const json::Value*> Encode(const ClientCompletionItemInsertTextModeOptions& in,
                                  json::Builder& b);

bool operator==(const ClientCompletionItemOptions& lhs, const ClientCompletionItemOptions& rhs);
bool operator!=(const ClientCompletionItemOptions& lhs, const ClientCompletionItemOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientCompletionItemOptions& out);
Result<const json::Value*> Encode(const ClientCompletionItemOptions& in, json::Builder& b);

bool operator==(const ClientCompletionItemOptionsKind& lhs,
                const ClientCompletionItemOptionsKind& rhs);
bool operator!=(const ClientCompletionItemOptionsKind& lhs,
                const ClientCompletionItemOptionsKind& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientCompletionItemOptionsKind& out);
Result<const json::Value*> Encode(const ClientCompletionItemOptionsKind& in, json::Builder& b);

bool operator==(const CompletionListCapabilities& lhs, const CompletionListCapabilities& rhs);
bool operator!=(const CompletionListCapabilities& lhs, const CompletionListCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, CompletionListCapabilities& out);
Result<const json::Value*> Encode(const CompletionListCapabilities& in, json::Builder& b);

bool operator==(const CompletionClientCapabilities& lhs, const CompletionClientCapabilities& rhs);
bool operator!=(const CompletionClientCapabilities& lhs, const CompletionClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, CompletionClientCapabilities& out);
Result<const json::Value*> Encode(const CompletionClientCapabilities& in, json::Builder& b);

bool operator==(const HoverClientCapabilities& lhs, const HoverClientCapabilities& rhs);
bool operator!=(const HoverClientCapabilities& lhs, const HoverClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, HoverClientCapabilities& out);
Result<const json::Value*> Encode(const HoverClientCapabilities& in, json::Builder& b);

bool operator==(const ClientSignatureParameterInformationOptions& lhs,
                const ClientSignatureParameterInformationOptions& rhs);
bool operator!=(const ClientSignatureParameterInformationOptions& lhs,
                const ClientSignatureParameterInformationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientSignatureParameterInformationOptions& out);
Result<const json::Value*> Encode(const ClientSignatureParameterInformationOptions& in,
                                  json::Builder& b);

bool operator==(const ClientSignatureInformationOptions& lhs,
                const ClientSignatureInformationOptions& rhs);
bool operator!=(const ClientSignatureInformationOptions& lhs,
                const ClientSignatureInformationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientSignatureInformationOptions& out);
Result<const json::Value*> Encode(const ClientSignatureInformationOptions& in, json::Builder& b);

bool operator==(const SignatureHelpClientCapabilities& lhs,
                const SignatureHelpClientCapabilities& rhs);
bool operator!=(const SignatureHelpClientCapabilities& lhs,
                const SignatureHelpClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, SignatureHelpClientCapabilities& out);
Result<const json::Value*> Encode(const SignatureHelpClientCapabilities& in, json::Builder& b);

bool operator==(const DeclarationClientCapabilities& lhs, const DeclarationClientCapabilities& rhs);
bool operator!=(const DeclarationClientCapabilities& lhs, const DeclarationClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, DeclarationClientCapabilities& out);
Result<const json::Value*> Encode(const DeclarationClientCapabilities& in, json::Builder& b);

bool operator==(const DefinitionClientCapabilities& lhs, const DefinitionClientCapabilities& rhs);
bool operator!=(const DefinitionClientCapabilities& lhs, const DefinitionClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, DefinitionClientCapabilities& out);
Result<const json::Value*> Encode(const DefinitionClientCapabilities& in, json::Builder& b);

bool operator==(const TypeDefinitionClientCapabilities& lhs,
                const TypeDefinitionClientCapabilities& rhs);
bool operator!=(const TypeDefinitionClientCapabilities& lhs,
                const TypeDefinitionClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, TypeDefinitionClientCapabilities& out);
Result<const json::Value*> Encode(const TypeDefinitionClientCapabilities& in, json::Builder& b);

bool operator==(const ImplementationClientCapabilities& lhs,
                const ImplementationClientCapabilities& rhs);
bool operator!=(const ImplementationClientCapabilities& lhs,
                const ImplementationClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, ImplementationClientCapabilities& out);
Result<const json::Value*> Encode(const ImplementationClientCapabilities& in, json::Builder& b);

bool operator==(const ReferenceClientCapabilities& lhs, const ReferenceClientCapabilities& rhs);
bool operator!=(const ReferenceClientCapabilities& lhs, const ReferenceClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, ReferenceClientCapabilities& out);
Result<const json::Value*> Encode(const ReferenceClientCapabilities& in, json::Builder& b);

bool operator==(const DocumentHighlightClientCapabilities& lhs,
                const DocumentHighlightClientCapabilities& rhs);
bool operator!=(const DocumentHighlightClientCapabilities& lhs,
                const DocumentHighlightClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentHighlightClientCapabilities& out);
Result<const json::Value*> Encode(const DocumentHighlightClientCapabilities& in, json::Builder& b);

bool operator==(const DocumentSymbolClientCapabilities& lhs,
                const DocumentSymbolClientCapabilities& rhs);
bool operator!=(const DocumentSymbolClientCapabilities& lhs,
                const DocumentSymbolClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentSymbolClientCapabilities& out);
Result<const json::Value*> Encode(const DocumentSymbolClientCapabilities& in, json::Builder& b);

bool operator==(const ClientCodeActionKindOptions& lhs, const ClientCodeActionKindOptions& rhs);
bool operator!=(const ClientCodeActionKindOptions& lhs, const ClientCodeActionKindOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientCodeActionKindOptions& out);
Result<const json::Value*> Encode(const ClientCodeActionKindOptions& in, json::Builder& b);

bool operator==(const ClientCodeActionLiteralOptions& lhs,
                const ClientCodeActionLiteralOptions& rhs);
bool operator!=(const ClientCodeActionLiteralOptions& lhs,
                const ClientCodeActionLiteralOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientCodeActionLiteralOptions& out);
Result<const json::Value*> Encode(const ClientCodeActionLiteralOptions& in, json::Builder& b);

bool operator==(const ClientCodeActionResolveOptions& lhs,
                const ClientCodeActionResolveOptions& rhs);
bool operator!=(const ClientCodeActionResolveOptions& lhs,
                const ClientCodeActionResolveOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientCodeActionResolveOptions& out);
Result<const json::Value*> Encode(const ClientCodeActionResolveOptions& in, json::Builder& b);

bool operator==(const CodeActionClientCapabilities& lhs, const CodeActionClientCapabilities& rhs);
bool operator!=(const CodeActionClientCapabilities& lhs, const CodeActionClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeActionClientCapabilities& out);
Result<const json::Value*> Encode(const CodeActionClientCapabilities& in, json::Builder& b);

bool operator==(const CodeLensClientCapabilities& lhs, const CodeLensClientCapabilities& rhs);
bool operator!=(const CodeLensClientCapabilities& lhs, const CodeLensClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeLensClientCapabilities& out);
Result<const json::Value*> Encode(const CodeLensClientCapabilities& in, json::Builder& b);

bool operator==(const DocumentLinkClientCapabilities& lhs,
                const DocumentLinkClientCapabilities& rhs);
bool operator!=(const DocumentLinkClientCapabilities& lhs,
                const DocumentLinkClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentLinkClientCapabilities& out);
Result<const json::Value*> Encode(const DocumentLinkClientCapabilities& in, json::Builder& b);

bool operator==(const DocumentColorClientCapabilities& lhs,
                const DocumentColorClientCapabilities& rhs);
bool operator!=(const DocumentColorClientCapabilities& lhs,
                const DocumentColorClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentColorClientCapabilities& out);
Result<const json::Value*> Encode(const DocumentColorClientCapabilities& in, json::Builder& b);

bool operator==(const DocumentFormattingClientCapabilities& lhs,
                const DocumentFormattingClientCapabilities& rhs);
bool operator!=(const DocumentFormattingClientCapabilities& lhs,
                const DocumentFormattingClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentFormattingClientCapabilities& out);
Result<const json::Value*> Encode(const DocumentFormattingClientCapabilities& in, json::Builder& b);

bool operator==(const DocumentRangeFormattingClientCapabilities& lhs,
                const DocumentRangeFormattingClientCapabilities& rhs);
bool operator!=(const DocumentRangeFormattingClientCapabilities& lhs,
                const DocumentRangeFormattingClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentRangeFormattingClientCapabilities& out);
Result<const json::Value*> Encode(const DocumentRangeFormattingClientCapabilities& in,
                                  json::Builder& b);

bool operator==(const DocumentOnTypeFormattingClientCapabilities& lhs,
                const DocumentOnTypeFormattingClientCapabilities& rhs);
bool operator!=(const DocumentOnTypeFormattingClientCapabilities& lhs,
                const DocumentOnTypeFormattingClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentOnTypeFormattingClientCapabilities& out);
Result<const json::Value*> Encode(const DocumentOnTypeFormattingClientCapabilities& in,
                                  json::Builder& b);

bool operator==(const RenameClientCapabilities& lhs, const RenameClientCapabilities& rhs);
bool operator!=(const RenameClientCapabilities& lhs, const RenameClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, RenameClientCapabilities& out);
Result<const json::Value*> Encode(const RenameClientCapabilities& in, json::Builder& b);

bool operator==(const ClientFoldingRangeKindOptions& lhs, const ClientFoldingRangeKindOptions& rhs);
bool operator!=(const ClientFoldingRangeKindOptions& lhs, const ClientFoldingRangeKindOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientFoldingRangeKindOptions& out);
Result<const json::Value*> Encode(const ClientFoldingRangeKindOptions& in, json::Builder& b);

bool operator==(const ClientFoldingRangeOptions& lhs, const ClientFoldingRangeOptions& rhs);
bool operator!=(const ClientFoldingRangeOptions& lhs, const ClientFoldingRangeOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientFoldingRangeOptions& out);
Result<const json::Value*> Encode(const ClientFoldingRangeOptions& in, json::Builder& b);

bool operator==(const FoldingRangeClientCapabilities& lhs,
                const FoldingRangeClientCapabilities& rhs);
bool operator!=(const FoldingRangeClientCapabilities& lhs,
                const FoldingRangeClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, FoldingRangeClientCapabilities& out);
Result<const json::Value*> Encode(const FoldingRangeClientCapabilities& in, json::Builder& b);

bool operator==(const SelectionRangeClientCapabilities& lhs,
                const SelectionRangeClientCapabilities& rhs);
bool operator!=(const SelectionRangeClientCapabilities& lhs,
                const SelectionRangeClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, SelectionRangeClientCapabilities& out);
Result<const json::Value*> Encode(const SelectionRangeClientCapabilities& in, json::Builder& b);

bool operator==(const ClientDiagnosticsTagOptions& lhs, const ClientDiagnosticsTagOptions& rhs);
bool operator!=(const ClientDiagnosticsTagOptions& lhs, const ClientDiagnosticsTagOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientDiagnosticsTagOptions& out);
Result<const json::Value*> Encode(const ClientDiagnosticsTagOptions& in, json::Builder& b);

bool operator==(const PublishDiagnosticsClientCapabilities& lhs,
                const PublishDiagnosticsClientCapabilities& rhs);
bool operator!=(const PublishDiagnosticsClientCapabilities& lhs,
                const PublishDiagnosticsClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, PublishDiagnosticsClientCapabilities& out);
Result<const json::Value*> Encode(const PublishDiagnosticsClientCapabilities& in, json::Builder& b);

bool operator==(const CallHierarchyClientCapabilities& lhs,
                const CallHierarchyClientCapabilities& rhs);
bool operator!=(const CallHierarchyClientCapabilities& lhs,
                const CallHierarchyClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, CallHierarchyClientCapabilities& out);
Result<const json::Value*> Encode(const CallHierarchyClientCapabilities& in, json::Builder& b);

bool operator==(const ClientSemanticTokensRequestFullDelta& lhs,
                const ClientSemanticTokensRequestFullDelta& rhs);
bool operator!=(const ClientSemanticTokensRequestFullDelta& lhs,
                const ClientSemanticTokensRequestFullDelta& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientSemanticTokensRequestFullDelta& out);
Result<const json::Value*> Encode(const ClientSemanticTokensRequestFullDelta& in, json::Builder& b);

bool operator==(const ClientSemanticTokensRequestOptions& lhs,
                const ClientSemanticTokensRequestOptions& rhs);
bool operator!=(const ClientSemanticTokensRequestOptions& lhs,
                const ClientSemanticTokensRequestOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientSemanticTokensRequestOptions& out);
Result<const json::Value*> Encode(const ClientSemanticTokensRequestOptions& in, json::Builder& b);
bool operator==(const ClientSemanticTokensRequestOptions::Range& lhs,
                const ClientSemanticTokensRequestOptions::Range& rhs);
bool operator!=(const ClientSemanticTokensRequestOptions::Range& lhs,
                const ClientSemanticTokensRequestOptions::Range& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientSemanticTokensRequestOptions::Range& out);
Result<const json::Value*> Encode(const ClientSemanticTokensRequestOptions::Range& in,
                                  json::Builder& b);

bool operator==(const SemanticTokensClientCapabilities& lhs,
                const SemanticTokensClientCapabilities& rhs);
bool operator!=(const SemanticTokensClientCapabilities& lhs,
                const SemanticTokensClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, SemanticTokensClientCapabilities& out);
Result<const json::Value*> Encode(const SemanticTokensClientCapabilities& in, json::Builder& b);

bool operator==(const LinkedEditingRangeClientCapabilities& lhs,
                const LinkedEditingRangeClientCapabilities& rhs);
bool operator!=(const LinkedEditingRangeClientCapabilities& lhs,
                const LinkedEditingRangeClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, LinkedEditingRangeClientCapabilities& out);
Result<const json::Value*> Encode(const LinkedEditingRangeClientCapabilities& in, json::Builder& b);

bool operator==(const MonikerClientCapabilities& lhs, const MonikerClientCapabilities& rhs);
bool operator!=(const MonikerClientCapabilities& lhs, const MonikerClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, MonikerClientCapabilities& out);
Result<const json::Value*> Encode(const MonikerClientCapabilities& in, json::Builder& b);

bool operator==(const TypeHierarchyClientCapabilities& lhs,
                const TypeHierarchyClientCapabilities& rhs);
bool operator!=(const TypeHierarchyClientCapabilities& lhs,
                const TypeHierarchyClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, TypeHierarchyClientCapabilities& out);
Result<const json::Value*> Encode(const TypeHierarchyClientCapabilities& in, json::Builder& b);

bool operator==(const InlineValueClientCapabilities& lhs, const InlineValueClientCapabilities& rhs);
bool operator!=(const InlineValueClientCapabilities& lhs, const InlineValueClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineValueClientCapabilities& out);
Result<const json::Value*> Encode(const InlineValueClientCapabilities& in, json::Builder& b);

bool operator==(const ClientInlayHintResolveOptions& lhs, const ClientInlayHintResolveOptions& rhs);
bool operator!=(const ClientInlayHintResolveOptions& lhs, const ClientInlayHintResolveOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientInlayHintResolveOptions& out);
Result<const json::Value*> Encode(const ClientInlayHintResolveOptions& in, json::Builder& b);

bool operator==(const InlayHintClientCapabilities& lhs, const InlayHintClientCapabilities& rhs);
bool operator!=(const InlayHintClientCapabilities& lhs, const InlayHintClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, InlayHintClientCapabilities& out);
Result<const json::Value*> Encode(const InlayHintClientCapabilities& in, json::Builder& b);

bool operator==(const DiagnosticClientCapabilities& lhs, const DiagnosticClientCapabilities& rhs);
bool operator!=(const DiagnosticClientCapabilities& lhs, const DiagnosticClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, DiagnosticClientCapabilities& out);
Result<const json::Value*> Encode(const DiagnosticClientCapabilities& in, json::Builder& b);

bool operator==(const InlineCompletionClientCapabilities& lhs,
                const InlineCompletionClientCapabilities& rhs);
bool operator!=(const InlineCompletionClientCapabilities& lhs,
                const InlineCompletionClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineCompletionClientCapabilities& out);
Result<const json::Value*> Encode(const InlineCompletionClientCapabilities& in, json::Builder& b);

bool operator==(const TextDocumentClientCapabilities& lhs,
                const TextDocumentClientCapabilities& rhs);
bool operator!=(const TextDocumentClientCapabilities& lhs,
                const TextDocumentClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentClientCapabilities& out);
Result<const json::Value*> Encode(const TextDocumentClientCapabilities& in, json::Builder& b);

bool operator==(const NotebookDocumentSyncClientCapabilities& lhs,
                const NotebookDocumentSyncClientCapabilities& rhs);
bool operator!=(const NotebookDocumentSyncClientCapabilities& lhs,
                const NotebookDocumentSyncClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentSyncClientCapabilities& out);
Result<const json::Value*> Encode(const NotebookDocumentSyncClientCapabilities& in,
                                  json::Builder& b);

bool operator==(const NotebookDocumentClientCapabilities& lhs,
                const NotebookDocumentClientCapabilities& rhs);
bool operator!=(const NotebookDocumentClientCapabilities& lhs,
                const NotebookDocumentClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentClientCapabilities& out);
Result<const json::Value*> Encode(const NotebookDocumentClientCapabilities& in, json::Builder& b);

bool operator==(const ClientShowMessageActionItemOptions& lhs,
                const ClientShowMessageActionItemOptions& rhs);
bool operator!=(const ClientShowMessageActionItemOptions& lhs,
                const ClientShowMessageActionItemOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientShowMessageActionItemOptions& out);
Result<const json::Value*> Encode(const ClientShowMessageActionItemOptions& in, json::Builder& b);

bool operator==(const ShowMessageRequestClientCapabilities& lhs,
                const ShowMessageRequestClientCapabilities& rhs);
bool operator!=(const ShowMessageRequestClientCapabilities& lhs,
                const ShowMessageRequestClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, ShowMessageRequestClientCapabilities& out);
Result<const json::Value*> Encode(const ShowMessageRequestClientCapabilities& in, json::Builder& b);

bool operator==(const ShowDocumentClientCapabilities& lhs,
                const ShowDocumentClientCapabilities& rhs);
bool operator!=(const ShowDocumentClientCapabilities& lhs,
                const ShowDocumentClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, ShowDocumentClientCapabilities& out);
Result<const json::Value*> Encode(const ShowDocumentClientCapabilities& in, json::Builder& b);

bool operator==(const WindowClientCapabilities& lhs, const WindowClientCapabilities& rhs);
bool operator!=(const WindowClientCapabilities& lhs, const WindowClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, WindowClientCapabilities& out);
Result<const json::Value*> Encode(const WindowClientCapabilities& in, json::Builder& b);

bool operator==(const StaleRequestSupportOptions& lhs, const StaleRequestSupportOptions& rhs);
bool operator!=(const StaleRequestSupportOptions& lhs, const StaleRequestSupportOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, StaleRequestSupportOptions& out);
Result<const json::Value*> Encode(const StaleRequestSupportOptions& in, json::Builder& b);

bool operator==(const RegularExpressionsClientCapabilities& lhs,
                const RegularExpressionsClientCapabilities& rhs);
bool operator!=(const RegularExpressionsClientCapabilities& lhs,
                const RegularExpressionsClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, RegularExpressionsClientCapabilities& out);
Result<const json::Value*> Encode(const RegularExpressionsClientCapabilities& in, json::Builder& b);

bool operator==(const MarkdownClientCapabilities& lhs, const MarkdownClientCapabilities& rhs);
bool operator!=(const MarkdownClientCapabilities& lhs, const MarkdownClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, MarkdownClientCapabilities& out);
Result<const json::Value*> Encode(const MarkdownClientCapabilities& in, json::Builder& b);

bool operator==(const GeneralClientCapabilities& lhs, const GeneralClientCapabilities& rhs);
bool operator!=(const GeneralClientCapabilities& lhs, const GeneralClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, GeneralClientCapabilities& out);
Result<const json::Value*> Encode(const GeneralClientCapabilities& in, json::Builder& b);

bool operator==(const ClientCapabilities& lhs, const ClientCapabilities& rhs);
bool operator!=(const ClientCapabilities& lhs, const ClientCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, ClientCapabilities& out);
Result<const json::Value*> Encode(const ClientCapabilities& in, json::Builder& b);

bool operator==(const InitializeParamsBase& lhs, const InitializeParamsBase& rhs);
bool operator!=(const InitializeParamsBase& lhs, const InitializeParamsBase& rhs);
Result<SuccessType> Decode(const json::Value& v, InitializeParamsBase& out);
Result<const json::Value*> Encode(const InitializeParamsBase& in, json::Builder& b);

bool operator==(const WorkspaceFoldersInitializeParams& lhs,
                const WorkspaceFoldersInitializeParams& rhs);
bool operator!=(const WorkspaceFoldersInitializeParams& lhs,
                const WorkspaceFoldersInitializeParams& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceFoldersInitializeParams& out);
Result<const json::Value*> Encode(const WorkspaceFoldersInitializeParams& in, json::Builder& b);

bool operator==(const InitializeParams& lhs, const InitializeParams& rhs);
bool operator!=(const InitializeParams& lhs, const InitializeParams& rhs);
Result<SuccessType> Decode(const json::Value& v, InitializeParams& out);
Result<const json::Value*> Encode(const InitializeParams& in, json::Builder& b);

bool operator==(const SaveOptions& lhs, const SaveOptions& rhs);
bool operator!=(const SaveOptions& lhs, const SaveOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, SaveOptions& out);
Result<const json::Value*> Encode(const SaveOptions& in, json::Builder& b);

bool operator==(const TextDocumentSyncOptions& lhs, const TextDocumentSyncOptions& rhs);
bool operator!=(const TextDocumentSyncOptions& lhs, const TextDocumentSyncOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentSyncOptions& out);
Result<const json::Value*> Encode(const TextDocumentSyncOptions& in, json::Builder& b);

bool operator==(const NotebookCellLanguage& lhs, const NotebookCellLanguage& rhs);
bool operator!=(const NotebookCellLanguage& lhs, const NotebookCellLanguage& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookCellLanguage& out);
Result<const json::Value*> Encode(const NotebookCellLanguage& in, json::Builder& b);

bool operator==(const NotebookDocumentFilterWithCells& lhs,
                const NotebookDocumentFilterWithCells& rhs);
bool operator!=(const NotebookDocumentFilterWithCells& lhs,
                const NotebookDocumentFilterWithCells& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentFilterWithCells& out);
Result<const json::Value*> Encode(const NotebookDocumentFilterWithCells& in, json::Builder& b);

bool operator==(const NotebookDocumentFilterWithNotebook& lhs,
                const NotebookDocumentFilterWithNotebook& rhs);
bool operator!=(const NotebookDocumentFilterWithNotebook& lhs,
                const NotebookDocumentFilterWithNotebook& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentFilterWithNotebook& out);
Result<const json::Value*> Encode(const NotebookDocumentFilterWithNotebook& in, json::Builder& b);

bool operator==(const NotebookDocumentSyncOptions& lhs, const NotebookDocumentSyncOptions& rhs);
bool operator!=(const NotebookDocumentSyncOptions& lhs, const NotebookDocumentSyncOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentSyncOptions& out);
Result<const json::Value*> Encode(const NotebookDocumentSyncOptions& in, json::Builder& b);

bool operator==(const NotebookDocumentSyncRegistrationOptions& lhs,
                const NotebookDocumentSyncRegistrationOptions& rhs);
bool operator!=(const NotebookDocumentSyncRegistrationOptions& lhs,
                const NotebookDocumentSyncRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentSyncRegistrationOptions& out);
Result<const json::Value*> Encode(const NotebookDocumentSyncRegistrationOptions& in,
                                  json::Builder& b);

bool operator==(const ServerCompletionItemOptions& lhs, const ServerCompletionItemOptions& rhs);
bool operator!=(const ServerCompletionItemOptions& lhs, const ServerCompletionItemOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ServerCompletionItemOptions& out);
Result<const json::Value*> Encode(const ServerCompletionItemOptions& in, json::Builder& b);

bool operator==(const CompletionOptions& lhs, const CompletionOptions& rhs);
bool operator!=(const CompletionOptions& lhs, const CompletionOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, CompletionOptions& out);
Result<const json::Value*> Encode(const CompletionOptions& in, json::Builder& b);

bool operator==(const HoverOptions& lhs, const HoverOptions& rhs);
bool operator!=(const HoverOptions& lhs, const HoverOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, HoverOptions& out);
Result<const json::Value*> Encode(const HoverOptions& in, json::Builder& b);

bool operator==(const SignatureHelpOptions& lhs, const SignatureHelpOptions& rhs);
bool operator!=(const SignatureHelpOptions& lhs, const SignatureHelpOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, SignatureHelpOptions& out);
Result<const json::Value*> Encode(const SignatureHelpOptions& in, json::Builder& b);

bool operator==(const DefinitionOptions& lhs, const DefinitionOptions& rhs);
bool operator!=(const DefinitionOptions& lhs, const DefinitionOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DefinitionOptions& out);
Result<const json::Value*> Encode(const DefinitionOptions& in, json::Builder& b);

bool operator==(const ReferenceOptions& lhs, const ReferenceOptions& rhs);
bool operator!=(const ReferenceOptions& lhs, const ReferenceOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ReferenceOptions& out);
Result<const json::Value*> Encode(const ReferenceOptions& in, json::Builder& b);

bool operator==(const DocumentHighlightOptions& lhs, const DocumentHighlightOptions& rhs);
bool operator!=(const DocumentHighlightOptions& lhs, const DocumentHighlightOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentHighlightOptions& out);
Result<const json::Value*> Encode(const DocumentHighlightOptions& in, json::Builder& b);

bool operator==(const DocumentSymbolOptions& lhs, const DocumentSymbolOptions& rhs);
bool operator!=(const DocumentSymbolOptions& lhs, const DocumentSymbolOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentSymbolOptions& out);
Result<const json::Value*> Encode(const DocumentSymbolOptions& in, json::Builder& b);

bool operator==(const CodeActionOptions& lhs, const CodeActionOptions& rhs);
bool operator!=(const CodeActionOptions& lhs, const CodeActionOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeActionOptions& out);
Result<const json::Value*> Encode(const CodeActionOptions& in, json::Builder& b);

bool operator==(const CodeLensOptions& lhs, const CodeLensOptions& rhs);
bool operator!=(const CodeLensOptions& lhs, const CodeLensOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeLensOptions& out);
Result<const json::Value*> Encode(const CodeLensOptions& in, json::Builder& b);

bool operator==(const DocumentLinkOptions& lhs, const DocumentLinkOptions& rhs);
bool operator!=(const DocumentLinkOptions& lhs, const DocumentLinkOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentLinkOptions& out);
Result<const json::Value*> Encode(const DocumentLinkOptions& in, json::Builder& b);

bool operator==(const WorkspaceSymbolOptions& lhs, const WorkspaceSymbolOptions& rhs);
bool operator!=(const WorkspaceSymbolOptions& lhs, const WorkspaceSymbolOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceSymbolOptions& out);
Result<const json::Value*> Encode(const WorkspaceSymbolOptions& in, json::Builder& b);

bool operator==(const DocumentFormattingOptions& lhs, const DocumentFormattingOptions& rhs);
bool operator!=(const DocumentFormattingOptions& lhs, const DocumentFormattingOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentFormattingOptions& out);
Result<const json::Value*> Encode(const DocumentFormattingOptions& in, json::Builder& b);

bool operator==(const DocumentRangeFormattingOptions& lhs,
                const DocumentRangeFormattingOptions& rhs);
bool operator!=(const DocumentRangeFormattingOptions& lhs,
                const DocumentRangeFormattingOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentRangeFormattingOptions& out);
Result<const json::Value*> Encode(const DocumentRangeFormattingOptions& in, json::Builder& b);

bool operator==(const DocumentOnTypeFormattingOptions& lhs,
                const DocumentOnTypeFormattingOptions& rhs);
bool operator!=(const DocumentOnTypeFormattingOptions& lhs,
                const DocumentOnTypeFormattingOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentOnTypeFormattingOptions& out);
Result<const json::Value*> Encode(const DocumentOnTypeFormattingOptions& in, json::Builder& b);

bool operator==(const RenameOptions& lhs, const RenameOptions& rhs);
bool operator!=(const RenameOptions& lhs, const RenameOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, RenameOptions& out);
Result<const json::Value*> Encode(const RenameOptions& in, json::Builder& b);

bool operator==(const ExecuteCommandOptions& lhs, const ExecuteCommandOptions& rhs);
bool operator!=(const ExecuteCommandOptions& lhs, const ExecuteCommandOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ExecuteCommandOptions& out);
Result<const json::Value*> Encode(const ExecuteCommandOptions& in, json::Builder& b);

bool operator==(const WorkspaceFoldersServerCapabilities& lhs,
                const WorkspaceFoldersServerCapabilities& rhs);
bool operator!=(const WorkspaceFoldersServerCapabilities& lhs,
                const WorkspaceFoldersServerCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceFoldersServerCapabilities& out);
Result<const json::Value*> Encode(const WorkspaceFoldersServerCapabilities& in, json::Builder& b);

bool operator==(const FileOperationOptions& lhs, const FileOperationOptions& rhs);
bool operator!=(const FileOperationOptions& lhs, const FileOperationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, FileOperationOptions& out);
Result<const json::Value*> Encode(const FileOperationOptions& in, json::Builder& b);

bool operator==(const WorkspaceOptions& lhs, const WorkspaceOptions& rhs);
bool operator!=(const WorkspaceOptions& lhs, const WorkspaceOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceOptions& out);
Result<const json::Value*> Encode(const WorkspaceOptions& in, json::Builder& b);

bool operator==(const ServerCapabilities& lhs, const ServerCapabilities& rhs);
bool operator!=(const ServerCapabilities& lhs, const ServerCapabilities& rhs);
Result<SuccessType> Decode(const json::Value& v, ServerCapabilities& out);
Result<const json::Value*> Encode(const ServerCapabilities& in, json::Builder& b);

bool operator==(const ServerInfo& lhs, const ServerInfo& rhs);
bool operator!=(const ServerInfo& lhs, const ServerInfo& rhs);
Result<SuccessType> Decode(const json::Value& v, ServerInfo& out);
Result<const json::Value*> Encode(const ServerInfo& in, json::Builder& b);

bool operator==(const InitializeResult& lhs, const InitializeResult& rhs);
bool operator!=(const InitializeResult& lhs, const InitializeResult& rhs);
Result<SuccessType> Decode(const json::Value& v, InitializeResult& out);
Result<const json::Value*> Encode(const InitializeResult& in, json::Builder& b);

bool operator==(const InitializeError& lhs, const InitializeError& rhs);
bool operator!=(const InitializeError& lhs, const InitializeError& rhs);
Result<SuccessType> Decode(const json::Value& v, InitializeError& out);
Result<const json::Value*> Encode(const InitializeError& in, json::Builder& b);

bool operator==(const InitializedParams& lhs, const InitializedParams& rhs);
bool operator!=(const InitializedParams& lhs, const InitializedParams& rhs);
Result<SuccessType> Decode(const json::Value& v, InitializedParams& out);
Result<const json::Value*> Encode(const InitializedParams& in, json::Builder& b);

bool operator==(const DidChangeConfigurationParams& lhs, const DidChangeConfigurationParams& rhs);
bool operator!=(const DidChangeConfigurationParams& lhs, const DidChangeConfigurationParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DidChangeConfigurationParams& out);
Result<const json::Value*> Encode(const DidChangeConfigurationParams& in, json::Builder& b);

bool operator==(const DidChangeConfigurationRegistrationOptions& lhs,
                const DidChangeConfigurationRegistrationOptions& rhs);
bool operator!=(const DidChangeConfigurationRegistrationOptions& lhs,
                const DidChangeConfigurationRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DidChangeConfigurationRegistrationOptions& out);
Result<const json::Value*> Encode(const DidChangeConfigurationRegistrationOptions& in,
                                  json::Builder& b);

bool operator==(const ShowMessageParams& lhs, const ShowMessageParams& rhs);
bool operator!=(const ShowMessageParams& lhs, const ShowMessageParams& rhs);
Result<SuccessType> Decode(const json::Value& v, ShowMessageParams& out);
Result<const json::Value*> Encode(const ShowMessageParams& in, json::Builder& b);

bool operator==(const MessageActionItem& lhs, const MessageActionItem& rhs);
bool operator!=(const MessageActionItem& lhs, const MessageActionItem& rhs);
Result<SuccessType> Decode(const json::Value& v, MessageActionItem& out);
Result<const json::Value*> Encode(const MessageActionItem& in, json::Builder& b);

bool operator==(const ShowMessageRequestParams& lhs, const ShowMessageRequestParams& rhs);
bool operator!=(const ShowMessageRequestParams& lhs, const ShowMessageRequestParams& rhs);
Result<SuccessType> Decode(const json::Value& v, ShowMessageRequestParams& out);
Result<const json::Value*> Encode(const ShowMessageRequestParams& in, json::Builder& b);

bool operator==(const LogMessageParams& lhs, const LogMessageParams& rhs);
bool operator!=(const LogMessageParams& lhs, const LogMessageParams& rhs);
Result<SuccessType> Decode(const json::Value& v, LogMessageParams& out);
Result<const json::Value*> Encode(const LogMessageParams& in, json::Builder& b);

bool operator==(const DidOpenTextDocumentParams& lhs, const DidOpenTextDocumentParams& rhs);
bool operator!=(const DidOpenTextDocumentParams& lhs, const DidOpenTextDocumentParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DidOpenTextDocumentParams& out);
Result<const json::Value*> Encode(const DidOpenTextDocumentParams& in, json::Builder& b);

bool operator==(const DidChangeTextDocumentParams& lhs, const DidChangeTextDocumentParams& rhs);
bool operator!=(const DidChangeTextDocumentParams& lhs, const DidChangeTextDocumentParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DidChangeTextDocumentParams& out);
Result<const json::Value*> Encode(const DidChangeTextDocumentParams& in, json::Builder& b);

bool operator==(const TextDocumentChangeRegistrationOptions& lhs,
                const TextDocumentChangeRegistrationOptions& rhs);
bool operator!=(const TextDocumentChangeRegistrationOptions& lhs,
                const TextDocumentChangeRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentChangeRegistrationOptions& out);
Result<const json::Value*> Encode(const TextDocumentChangeRegistrationOptions& in,
                                  json::Builder& b);

bool operator==(const DidCloseTextDocumentParams& lhs, const DidCloseTextDocumentParams& rhs);
bool operator!=(const DidCloseTextDocumentParams& lhs, const DidCloseTextDocumentParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DidCloseTextDocumentParams& out);
Result<const json::Value*> Encode(const DidCloseTextDocumentParams& in, json::Builder& b);

bool operator==(const DidSaveTextDocumentParams& lhs, const DidSaveTextDocumentParams& rhs);
bool operator!=(const DidSaveTextDocumentParams& lhs, const DidSaveTextDocumentParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DidSaveTextDocumentParams& out);
Result<const json::Value*> Encode(const DidSaveTextDocumentParams& in, json::Builder& b);

bool operator==(const TextDocumentSaveRegistrationOptions& lhs,
                const TextDocumentSaveRegistrationOptions& rhs);
bool operator!=(const TextDocumentSaveRegistrationOptions& lhs,
                const TextDocumentSaveRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentSaveRegistrationOptions& out);
Result<const json::Value*> Encode(const TextDocumentSaveRegistrationOptions& in, json::Builder& b);

bool operator==(const WillSaveTextDocumentParams& lhs, const WillSaveTextDocumentParams& rhs);
bool operator!=(const WillSaveTextDocumentParams& lhs, const WillSaveTextDocumentParams& rhs);
Result<SuccessType> Decode(const json::Value& v, WillSaveTextDocumentParams& out);
Result<const json::Value*> Encode(const WillSaveTextDocumentParams& in, json::Builder& b);

bool operator==(const FileEvent& lhs, const FileEvent& rhs);
bool operator!=(const FileEvent& lhs, const FileEvent& rhs);
Result<SuccessType> Decode(const json::Value& v, FileEvent& out);
Result<const json::Value*> Encode(const FileEvent& in, json::Builder& b);

bool operator==(const DidChangeWatchedFilesParams& lhs, const DidChangeWatchedFilesParams& rhs);
bool operator!=(const DidChangeWatchedFilesParams& lhs, const DidChangeWatchedFilesParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DidChangeWatchedFilesParams& out);
Result<const json::Value*> Encode(const DidChangeWatchedFilesParams& in, json::Builder& b);

bool operator==(const FileSystemWatcher& lhs, const FileSystemWatcher& rhs);
bool operator!=(const FileSystemWatcher& lhs, const FileSystemWatcher& rhs);
Result<SuccessType> Decode(const json::Value& v, FileSystemWatcher& out);
Result<const json::Value*> Encode(const FileSystemWatcher& in, json::Builder& b);

bool operator==(const DidChangeWatchedFilesRegistrationOptions& lhs,
                const DidChangeWatchedFilesRegistrationOptions& rhs);
bool operator!=(const DidChangeWatchedFilesRegistrationOptions& lhs,
                const DidChangeWatchedFilesRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DidChangeWatchedFilesRegistrationOptions& out);
Result<const json::Value*> Encode(const DidChangeWatchedFilesRegistrationOptions& in,
                                  json::Builder& b);

bool operator==(const PublishDiagnosticsParams& lhs, const PublishDiagnosticsParams& rhs);
bool operator!=(const PublishDiagnosticsParams& lhs, const PublishDiagnosticsParams& rhs);
Result<SuccessType> Decode(const json::Value& v, PublishDiagnosticsParams& out);
Result<const json::Value*> Encode(const PublishDiagnosticsParams& in, json::Builder& b);

bool operator==(const CompletionContext& lhs, const CompletionContext& rhs);
bool operator!=(const CompletionContext& lhs, const CompletionContext& rhs);
Result<SuccessType> Decode(const json::Value& v, CompletionContext& out);
Result<const json::Value*> Encode(const CompletionContext& in, json::Builder& b);

bool operator==(const CompletionParams& lhs, const CompletionParams& rhs);
bool operator!=(const CompletionParams& lhs, const CompletionParams& rhs);
Result<SuccessType> Decode(const json::Value& v, CompletionParams& out);
Result<const json::Value*> Encode(const CompletionParams& in, json::Builder& b);

bool operator==(const CompletionItemLabelDetails& lhs, const CompletionItemLabelDetails& rhs);
bool operator!=(const CompletionItemLabelDetails& lhs, const CompletionItemLabelDetails& rhs);
Result<SuccessType> Decode(const json::Value& v, CompletionItemLabelDetails& out);
Result<const json::Value*> Encode(const CompletionItemLabelDetails& in, json::Builder& b);

bool operator==(const InsertReplaceEdit& lhs, const InsertReplaceEdit& rhs);
bool operator!=(const InsertReplaceEdit& lhs, const InsertReplaceEdit& rhs);
Result<SuccessType> Decode(const json::Value& v, InsertReplaceEdit& out);
Result<const json::Value*> Encode(const InsertReplaceEdit& in, json::Builder& b);

bool operator==(const CompletionItem& lhs, const CompletionItem& rhs);
bool operator!=(const CompletionItem& lhs, const CompletionItem& rhs);
Result<SuccessType> Decode(const json::Value& v, CompletionItem& out);
Result<const json::Value*> Encode(const CompletionItem& in, json::Builder& b);

bool operator==(const EditRangeWithInsertReplace& lhs, const EditRangeWithInsertReplace& rhs);
bool operator!=(const EditRangeWithInsertReplace& lhs, const EditRangeWithInsertReplace& rhs);
Result<SuccessType> Decode(const json::Value& v, EditRangeWithInsertReplace& out);
Result<const json::Value*> Encode(const EditRangeWithInsertReplace& in, json::Builder& b);

bool operator==(const CompletionItemDefaults& lhs, const CompletionItemDefaults& rhs);
bool operator!=(const CompletionItemDefaults& lhs, const CompletionItemDefaults& rhs);
Result<SuccessType> Decode(const json::Value& v, CompletionItemDefaults& out);
Result<const json::Value*> Encode(const CompletionItemDefaults& in, json::Builder& b);

bool operator==(const CompletionList& lhs, const CompletionList& rhs);
bool operator!=(const CompletionList& lhs, const CompletionList& rhs);
Result<SuccessType> Decode(const json::Value& v, CompletionList& out);
Result<const json::Value*> Encode(const CompletionList& in, json::Builder& b);

bool operator==(const CompletionRegistrationOptions& lhs, const CompletionRegistrationOptions& rhs);
bool operator!=(const CompletionRegistrationOptions& lhs, const CompletionRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, CompletionRegistrationOptions& out);
Result<const json::Value*> Encode(const CompletionRegistrationOptions& in, json::Builder& b);

bool operator==(const HoverParams& lhs, const HoverParams& rhs);
bool operator!=(const HoverParams& lhs, const HoverParams& rhs);
Result<SuccessType> Decode(const json::Value& v, HoverParams& out);
Result<const json::Value*> Encode(const HoverParams& in, json::Builder& b);

bool operator==(const Hover& lhs, const Hover& rhs);
bool operator!=(const Hover& lhs, const Hover& rhs);
Result<SuccessType> Decode(const json::Value& v, Hover& out);
Result<const json::Value*> Encode(const Hover& in, json::Builder& b);

bool operator==(const HoverRegistrationOptions& lhs, const HoverRegistrationOptions& rhs);
bool operator!=(const HoverRegistrationOptions& lhs, const HoverRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, HoverRegistrationOptions& out);
Result<const json::Value*> Encode(const HoverRegistrationOptions& in, json::Builder& b);

bool operator==(const ParameterInformation& lhs, const ParameterInformation& rhs);
bool operator!=(const ParameterInformation& lhs, const ParameterInformation& rhs);
Result<SuccessType> Decode(const json::Value& v, ParameterInformation& out);
Result<const json::Value*> Encode(const ParameterInformation& in, json::Builder& b);

bool operator==(const SignatureInformation& lhs, const SignatureInformation& rhs);
bool operator!=(const SignatureInformation& lhs, const SignatureInformation& rhs);
Result<SuccessType> Decode(const json::Value& v, SignatureInformation& out);
Result<const json::Value*> Encode(const SignatureInformation& in, json::Builder& b);

bool operator==(const SignatureHelp& lhs, const SignatureHelp& rhs);
bool operator!=(const SignatureHelp& lhs, const SignatureHelp& rhs);
Result<SuccessType> Decode(const json::Value& v, SignatureHelp& out);
Result<const json::Value*> Encode(const SignatureHelp& in, json::Builder& b);

bool operator==(const SignatureHelpContext& lhs, const SignatureHelpContext& rhs);
bool operator!=(const SignatureHelpContext& lhs, const SignatureHelpContext& rhs);
Result<SuccessType> Decode(const json::Value& v, SignatureHelpContext& out);
Result<const json::Value*> Encode(const SignatureHelpContext& in, json::Builder& b);

bool operator==(const SignatureHelpParams& lhs, const SignatureHelpParams& rhs);
bool operator!=(const SignatureHelpParams& lhs, const SignatureHelpParams& rhs);
Result<SuccessType> Decode(const json::Value& v, SignatureHelpParams& out);
Result<const json::Value*> Encode(const SignatureHelpParams& in, json::Builder& b);

bool operator==(const SignatureHelpRegistrationOptions& lhs,
                const SignatureHelpRegistrationOptions& rhs);
bool operator!=(const SignatureHelpRegistrationOptions& lhs,
                const SignatureHelpRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, SignatureHelpRegistrationOptions& out);
Result<const json::Value*> Encode(const SignatureHelpRegistrationOptions& in, json::Builder& b);

bool operator==(const DefinitionParams& lhs, const DefinitionParams& rhs);
bool operator!=(const DefinitionParams& lhs, const DefinitionParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DefinitionParams& out);
Result<const json::Value*> Encode(const DefinitionParams& in, json::Builder& b);

bool operator==(const DefinitionRegistrationOptions& lhs, const DefinitionRegistrationOptions& rhs);
bool operator!=(const DefinitionRegistrationOptions& lhs, const DefinitionRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DefinitionRegistrationOptions& out);
Result<const json::Value*> Encode(const DefinitionRegistrationOptions& in, json::Builder& b);

bool operator==(const ReferenceContext& lhs, const ReferenceContext& rhs);
bool operator!=(const ReferenceContext& lhs, const ReferenceContext& rhs);
Result<SuccessType> Decode(const json::Value& v, ReferenceContext& out);
Result<const json::Value*> Encode(const ReferenceContext& in, json::Builder& b);

bool operator==(const ReferenceParams& lhs, const ReferenceParams& rhs);
bool operator!=(const ReferenceParams& lhs, const ReferenceParams& rhs);
Result<SuccessType> Decode(const json::Value& v, ReferenceParams& out);
Result<const json::Value*> Encode(const ReferenceParams& in, json::Builder& b);

bool operator==(const ReferenceRegistrationOptions& lhs, const ReferenceRegistrationOptions& rhs);
bool operator!=(const ReferenceRegistrationOptions& lhs, const ReferenceRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ReferenceRegistrationOptions& out);
Result<const json::Value*> Encode(const ReferenceRegistrationOptions& in, json::Builder& b);

bool operator==(const DocumentHighlightParams& lhs, const DocumentHighlightParams& rhs);
bool operator!=(const DocumentHighlightParams& lhs, const DocumentHighlightParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentHighlightParams& out);
Result<const json::Value*> Encode(const DocumentHighlightParams& in, json::Builder& b);

bool operator==(const DocumentHighlight& lhs, const DocumentHighlight& rhs);
bool operator!=(const DocumentHighlight& lhs, const DocumentHighlight& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentHighlight& out);
Result<const json::Value*> Encode(const DocumentHighlight& in, json::Builder& b);

bool operator==(const DocumentHighlightRegistrationOptions& lhs,
                const DocumentHighlightRegistrationOptions& rhs);
bool operator!=(const DocumentHighlightRegistrationOptions& lhs,
                const DocumentHighlightRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentHighlightRegistrationOptions& out);
Result<const json::Value*> Encode(const DocumentHighlightRegistrationOptions& in, json::Builder& b);

bool operator==(const DocumentSymbolParams& lhs, const DocumentSymbolParams& rhs);
bool operator!=(const DocumentSymbolParams& lhs, const DocumentSymbolParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentSymbolParams& out);
Result<const json::Value*> Encode(const DocumentSymbolParams& in, json::Builder& b);

bool operator==(const BaseSymbolInformation& lhs, const BaseSymbolInformation& rhs);
bool operator!=(const BaseSymbolInformation& lhs, const BaseSymbolInformation& rhs);
Result<SuccessType> Decode(const json::Value& v, BaseSymbolInformation& out);
Result<const json::Value*> Encode(const BaseSymbolInformation& in, json::Builder& b);

bool operator==(const SymbolInformation& lhs, const SymbolInformation& rhs);
bool operator!=(const SymbolInformation& lhs, const SymbolInformation& rhs);
Result<SuccessType> Decode(const json::Value& v, SymbolInformation& out);
Result<const json::Value*> Encode(const SymbolInformation& in, json::Builder& b);

bool operator==(const DocumentSymbol& lhs, const DocumentSymbol& rhs);
bool operator!=(const DocumentSymbol& lhs, const DocumentSymbol& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentSymbol& out);
Result<const json::Value*> Encode(const DocumentSymbol& in, json::Builder& b);

bool operator==(const DocumentSymbolRegistrationOptions& lhs,
                const DocumentSymbolRegistrationOptions& rhs);
bool operator!=(const DocumentSymbolRegistrationOptions& lhs,
                const DocumentSymbolRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentSymbolRegistrationOptions& out);
Result<const json::Value*> Encode(const DocumentSymbolRegistrationOptions& in, json::Builder& b);

bool operator==(const CodeActionContext& lhs, const CodeActionContext& rhs);
bool operator!=(const CodeActionContext& lhs, const CodeActionContext& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeActionContext& out);
Result<const json::Value*> Encode(const CodeActionContext& in, json::Builder& b);

bool operator==(const CodeActionParams& lhs, const CodeActionParams& rhs);
bool operator!=(const CodeActionParams& lhs, const CodeActionParams& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeActionParams& out);
Result<const json::Value*> Encode(const CodeActionParams& in, json::Builder& b);

bool operator==(const CodeActionDisabled& lhs, const CodeActionDisabled& rhs);
bool operator!=(const CodeActionDisabled& lhs, const CodeActionDisabled& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeActionDisabled& out);
Result<const json::Value*> Encode(const CodeActionDisabled& in, json::Builder& b);

bool operator==(const CodeAction& lhs, const CodeAction& rhs);
bool operator!=(const CodeAction& lhs, const CodeAction& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeAction& out);
Result<const json::Value*> Encode(const CodeAction& in, json::Builder& b);

bool operator==(const CodeActionRegistrationOptions& lhs, const CodeActionRegistrationOptions& rhs);
bool operator!=(const CodeActionRegistrationOptions& lhs, const CodeActionRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeActionRegistrationOptions& out);
Result<const json::Value*> Encode(const CodeActionRegistrationOptions& in, json::Builder& b);

bool operator==(const WorkspaceSymbolParams& lhs, const WorkspaceSymbolParams& rhs);
bool operator!=(const WorkspaceSymbolParams& lhs, const WorkspaceSymbolParams& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceSymbolParams& out);
Result<const json::Value*> Encode(const WorkspaceSymbolParams& in, json::Builder& b);

bool operator==(const LocationUriOnly& lhs, const LocationUriOnly& rhs);
bool operator!=(const LocationUriOnly& lhs, const LocationUriOnly& rhs);
Result<SuccessType> Decode(const json::Value& v, LocationUriOnly& out);
Result<const json::Value*> Encode(const LocationUriOnly& in, json::Builder& b);

bool operator==(const WorkspaceSymbol& lhs, const WorkspaceSymbol& rhs);
bool operator!=(const WorkspaceSymbol& lhs, const WorkspaceSymbol& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceSymbol& out);
Result<const json::Value*> Encode(const WorkspaceSymbol& in, json::Builder& b);

bool operator==(const WorkspaceSymbolRegistrationOptions& lhs,
                const WorkspaceSymbolRegistrationOptions& rhs);
bool operator!=(const WorkspaceSymbolRegistrationOptions& lhs,
                const WorkspaceSymbolRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceSymbolRegistrationOptions& out);
Result<const json::Value*> Encode(const WorkspaceSymbolRegistrationOptions& in, json::Builder& b);

bool operator==(const CodeLensParams& lhs, const CodeLensParams& rhs);
bool operator!=(const CodeLensParams& lhs, const CodeLensParams& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeLensParams& out);
Result<const json::Value*> Encode(const CodeLensParams& in, json::Builder& b);

bool operator==(const CodeLens& lhs, const CodeLens& rhs);
bool operator!=(const CodeLens& lhs, const CodeLens& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeLens& out);
Result<const json::Value*> Encode(const CodeLens& in, json::Builder& b);

bool operator==(const CodeLensRegistrationOptions& lhs, const CodeLensRegistrationOptions& rhs);
bool operator!=(const CodeLensRegistrationOptions& lhs, const CodeLensRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, CodeLensRegistrationOptions& out);
Result<const json::Value*> Encode(const CodeLensRegistrationOptions& in, json::Builder& b);

bool operator==(const DocumentLinkParams& lhs, const DocumentLinkParams& rhs);
bool operator!=(const DocumentLinkParams& lhs, const DocumentLinkParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentLinkParams& out);
Result<const json::Value*> Encode(const DocumentLinkParams& in, json::Builder& b);

bool operator==(const DocumentLink& lhs, const DocumentLink& rhs);
bool operator!=(const DocumentLink& lhs, const DocumentLink& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentLink& out);
Result<const json::Value*> Encode(const DocumentLink& in, json::Builder& b);

bool operator==(const DocumentLinkRegistrationOptions& lhs,
                const DocumentLinkRegistrationOptions& rhs);
bool operator!=(const DocumentLinkRegistrationOptions& lhs,
                const DocumentLinkRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentLinkRegistrationOptions& out);
Result<const json::Value*> Encode(const DocumentLinkRegistrationOptions& in, json::Builder& b);

bool operator==(const FormattingOptions& lhs, const FormattingOptions& rhs);
bool operator!=(const FormattingOptions& lhs, const FormattingOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, FormattingOptions& out);
Result<const json::Value*> Encode(const FormattingOptions& in, json::Builder& b);

bool operator==(const DocumentFormattingParams& lhs, const DocumentFormattingParams& rhs);
bool operator!=(const DocumentFormattingParams& lhs, const DocumentFormattingParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentFormattingParams& out);
Result<const json::Value*> Encode(const DocumentFormattingParams& in, json::Builder& b);

bool operator==(const DocumentFormattingRegistrationOptions& lhs,
                const DocumentFormattingRegistrationOptions& rhs);
bool operator!=(const DocumentFormattingRegistrationOptions& lhs,
                const DocumentFormattingRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentFormattingRegistrationOptions& out);
Result<const json::Value*> Encode(const DocumentFormattingRegistrationOptions& in,
                                  json::Builder& b);

bool operator==(const DocumentRangeFormattingParams& lhs, const DocumentRangeFormattingParams& rhs);
bool operator!=(const DocumentRangeFormattingParams& lhs, const DocumentRangeFormattingParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentRangeFormattingParams& out);
Result<const json::Value*> Encode(const DocumentRangeFormattingParams& in, json::Builder& b);

bool operator==(const DocumentRangeFormattingRegistrationOptions& lhs,
                const DocumentRangeFormattingRegistrationOptions& rhs);
bool operator!=(const DocumentRangeFormattingRegistrationOptions& lhs,
                const DocumentRangeFormattingRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentRangeFormattingRegistrationOptions& out);
Result<const json::Value*> Encode(const DocumentRangeFormattingRegistrationOptions& in,
                                  json::Builder& b);

bool operator==(const DocumentRangesFormattingParams& lhs,
                const DocumentRangesFormattingParams& rhs);
bool operator!=(const DocumentRangesFormattingParams& lhs,
                const DocumentRangesFormattingParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentRangesFormattingParams& out);
Result<const json::Value*> Encode(const DocumentRangesFormattingParams& in, json::Builder& b);

bool operator==(const DocumentOnTypeFormattingParams& lhs,
                const DocumentOnTypeFormattingParams& rhs);
bool operator!=(const DocumentOnTypeFormattingParams& lhs,
                const DocumentOnTypeFormattingParams& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentOnTypeFormattingParams& out);
Result<const json::Value*> Encode(const DocumentOnTypeFormattingParams& in, json::Builder& b);

bool operator==(const DocumentOnTypeFormattingRegistrationOptions& lhs,
                const DocumentOnTypeFormattingRegistrationOptions& rhs);
bool operator!=(const DocumentOnTypeFormattingRegistrationOptions& lhs,
                const DocumentOnTypeFormattingRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, DocumentOnTypeFormattingRegistrationOptions& out);
Result<const json::Value*> Encode(const DocumentOnTypeFormattingRegistrationOptions& in,
                                  json::Builder& b);

bool operator==(const RenameParams& lhs, const RenameParams& rhs);
bool operator!=(const RenameParams& lhs, const RenameParams& rhs);
Result<SuccessType> Decode(const json::Value& v, RenameParams& out);
Result<const json::Value*> Encode(const RenameParams& in, json::Builder& b);

bool operator==(const RenameRegistrationOptions& lhs, const RenameRegistrationOptions& rhs);
bool operator!=(const RenameRegistrationOptions& lhs, const RenameRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, RenameRegistrationOptions& out);
Result<const json::Value*> Encode(const RenameRegistrationOptions& in, json::Builder& b);

bool operator==(const PrepareRenameParams& lhs, const PrepareRenameParams& rhs);
bool operator!=(const PrepareRenameParams& lhs, const PrepareRenameParams& rhs);
Result<SuccessType> Decode(const json::Value& v, PrepareRenameParams& out);
Result<const json::Value*> Encode(const PrepareRenameParams& in, json::Builder& b);

bool operator==(const ExecuteCommandParams& lhs, const ExecuteCommandParams& rhs);
bool operator!=(const ExecuteCommandParams& lhs, const ExecuteCommandParams& rhs);
Result<SuccessType> Decode(const json::Value& v, ExecuteCommandParams& out);
Result<const json::Value*> Encode(const ExecuteCommandParams& in, json::Builder& b);

bool operator==(const ExecuteCommandRegistrationOptions& lhs,
                const ExecuteCommandRegistrationOptions& rhs);
bool operator!=(const ExecuteCommandRegistrationOptions& lhs,
                const ExecuteCommandRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, ExecuteCommandRegistrationOptions& out);
Result<const json::Value*> Encode(const ExecuteCommandRegistrationOptions& in, json::Builder& b);

bool operator==(const ApplyWorkspaceEditParams& lhs, const ApplyWorkspaceEditParams& rhs);
bool operator!=(const ApplyWorkspaceEditParams& lhs, const ApplyWorkspaceEditParams& rhs);
Result<SuccessType> Decode(const json::Value& v, ApplyWorkspaceEditParams& out);
Result<const json::Value*> Encode(const ApplyWorkspaceEditParams& in, json::Builder& b);

bool operator==(const ApplyWorkspaceEditResult& lhs, const ApplyWorkspaceEditResult& rhs);
bool operator!=(const ApplyWorkspaceEditResult& lhs, const ApplyWorkspaceEditResult& rhs);
Result<SuccessType> Decode(const json::Value& v, ApplyWorkspaceEditResult& out);
Result<const json::Value*> Encode(const ApplyWorkspaceEditResult& in, json::Builder& b);

bool operator==(const WorkDoneProgressBegin& lhs, const WorkDoneProgressBegin& rhs);
bool operator!=(const WorkDoneProgressBegin& lhs, const WorkDoneProgressBegin& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkDoneProgressBegin& out);
Result<const json::Value*> Encode(const WorkDoneProgressBegin& in, json::Builder& b);

bool operator==(const WorkDoneProgressReport& lhs, const WorkDoneProgressReport& rhs);
bool operator!=(const WorkDoneProgressReport& lhs, const WorkDoneProgressReport& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkDoneProgressReport& out);
Result<const json::Value*> Encode(const WorkDoneProgressReport& in, json::Builder& b);

bool operator==(const WorkDoneProgressEnd& lhs, const WorkDoneProgressEnd& rhs);
bool operator!=(const WorkDoneProgressEnd& lhs, const WorkDoneProgressEnd& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkDoneProgressEnd& out);
Result<const json::Value*> Encode(const WorkDoneProgressEnd& in, json::Builder& b);

bool operator==(const SetTraceParams& lhs, const SetTraceParams& rhs);
bool operator!=(const SetTraceParams& lhs, const SetTraceParams& rhs);
Result<SuccessType> Decode(const json::Value& v, SetTraceParams& out);
Result<const json::Value*> Encode(const SetTraceParams& in, json::Builder& b);

bool operator==(const LogTraceParams& lhs, const LogTraceParams& rhs);
bool operator!=(const LogTraceParams& lhs, const LogTraceParams& rhs);
Result<SuccessType> Decode(const json::Value& v, LogTraceParams& out);
Result<const json::Value*> Encode(const LogTraceParams& in, json::Builder& b);

bool operator==(const CancelParams& lhs, const CancelParams& rhs);
bool operator!=(const CancelParams& lhs, const CancelParams& rhs);
Result<SuccessType> Decode(const json::Value& v, CancelParams& out);
Result<const json::Value*> Encode(const CancelParams& in, json::Builder& b);

bool operator==(const ProgressParams& lhs, const ProgressParams& rhs);
bool operator!=(const ProgressParams& lhs, const ProgressParams& rhs);
Result<SuccessType> Decode(const json::Value& v, ProgressParams& out);
Result<const json::Value*> Encode(const ProgressParams& in, json::Builder& b);

bool operator==(const WorkDoneProgressParams& lhs, const WorkDoneProgressParams& rhs);
bool operator!=(const WorkDoneProgressParams& lhs, const WorkDoneProgressParams& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkDoneProgressParams& out);
Result<const json::Value*> Encode(const WorkDoneProgressParams& in, json::Builder& b);

bool operator==(const PartialResultParams& lhs, const PartialResultParams& rhs);
bool operator!=(const PartialResultParams& lhs, const PartialResultParams& rhs);
Result<SuccessType> Decode(const json::Value& v, PartialResultParams& out);
Result<const json::Value*> Encode(const PartialResultParams& in, json::Builder& b);

bool operator==(const LocationLink& lhs, const LocationLink& rhs);
bool operator!=(const LocationLink& lhs, const LocationLink& rhs);
Result<SuccessType> Decode(const json::Value& v, LocationLink& out);
Result<const json::Value*> Encode(const LocationLink& in, json::Builder& b);

bool operator==(const StaticRegistrationOptions& lhs, const StaticRegistrationOptions& rhs);
bool operator!=(const StaticRegistrationOptions& lhs, const StaticRegistrationOptions& rhs);
Result<SuccessType> Decode(const json::Value& v, StaticRegistrationOptions& out);
Result<const json::Value*> Encode(const StaticRegistrationOptions& in, json::Builder& b);

bool operator==(const InlineValueText& lhs, const InlineValueText& rhs);
bool operator!=(const InlineValueText& lhs, const InlineValueText& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineValueText& out);
Result<const json::Value*> Encode(const InlineValueText& in, json::Builder& b);

bool operator==(const InlineValueVariableLookup& lhs, const InlineValueVariableLookup& rhs);
bool operator!=(const InlineValueVariableLookup& lhs, const InlineValueVariableLookup& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineValueVariableLookup& out);
Result<const json::Value*> Encode(const InlineValueVariableLookup& in, json::Builder& b);

bool operator==(const InlineValueEvaluatableExpression& lhs,
                const InlineValueEvaluatableExpression& rhs);
bool operator!=(const InlineValueEvaluatableExpression& lhs,
                const InlineValueEvaluatableExpression& rhs);
Result<SuccessType> Decode(const json::Value& v, InlineValueEvaluatableExpression& out);
Result<const json::Value*> Encode(const InlineValueEvaluatableExpression& in, json::Builder& b);

bool operator==(const RelatedFullDocumentDiagnosticReport& lhs,
                const RelatedFullDocumentDiagnosticReport& rhs);
bool operator!=(const RelatedFullDocumentDiagnosticReport& lhs,
                const RelatedFullDocumentDiagnosticReport& rhs);
Result<SuccessType> Decode(const json::Value& v, RelatedFullDocumentDiagnosticReport& out);
Result<const json::Value*> Encode(const RelatedFullDocumentDiagnosticReport& in, json::Builder& b);

bool operator==(const RelatedUnchangedDocumentDiagnosticReport& lhs,
                const RelatedUnchangedDocumentDiagnosticReport& rhs);
bool operator!=(const RelatedUnchangedDocumentDiagnosticReport& lhs,
                const RelatedUnchangedDocumentDiagnosticReport& rhs);
Result<SuccessType> Decode(const json::Value& v, RelatedUnchangedDocumentDiagnosticReport& out);
Result<const json::Value*> Encode(const RelatedUnchangedDocumentDiagnosticReport& in,
                                  json::Builder& b);

bool operator==(const PrepareRenamePlaceholder& lhs, const PrepareRenamePlaceholder& rhs);
bool operator!=(const PrepareRenamePlaceholder& lhs, const PrepareRenamePlaceholder& rhs);
Result<SuccessType> Decode(const json::Value& v, PrepareRenamePlaceholder& out);
Result<const json::Value*> Encode(const PrepareRenamePlaceholder& in, json::Builder& b);

bool operator==(const PrepareRenameDefaultBehavior& lhs, const PrepareRenameDefaultBehavior& rhs);
bool operator!=(const PrepareRenameDefaultBehavior& lhs, const PrepareRenameDefaultBehavior& rhs);
Result<SuccessType> Decode(const json::Value& v, PrepareRenameDefaultBehavior& out);
Result<const json::Value*> Encode(const PrepareRenameDefaultBehavior& in, json::Builder& b);

bool operator==(const WorkspaceFullDocumentDiagnosticReport& lhs,
                const WorkspaceFullDocumentDiagnosticReport& rhs);
bool operator!=(const WorkspaceFullDocumentDiagnosticReport& lhs,
                const WorkspaceFullDocumentDiagnosticReport& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceFullDocumentDiagnosticReport& out);
Result<const json::Value*> Encode(const WorkspaceFullDocumentDiagnosticReport& in,
                                  json::Builder& b);

bool operator==(const WorkspaceUnchangedDocumentDiagnosticReport& lhs,
                const WorkspaceUnchangedDocumentDiagnosticReport& rhs);
bool operator!=(const WorkspaceUnchangedDocumentDiagnosticReport& lhs,
                const WorkspaceUnchangedDocumentDiagnosticReport& rhs);
Result<SuccessType> Decode(const json::Value& v, WorkspaceUnchangedDocumentDiagnosticReport& out);
Result<const json::Value*> Encode(const WorkspaceUnchangedDocumentDiagnosticReport& in,
                                  json::Builder& b);

bool operator==(const TextDocumentContentChangePartial& lhs,
                const TextDocumentContentChangePartial& rhs);
bool operator!=(const TextDocumentContentChangePartial& lhs,
                const TextDocumentContentChangePartial& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentContentChangePartial& out);
Result<const json::Value*> Encode(const TextDocumentContentChangePartial& in, json::Builder& b);

bool operator==(const TextDocumentContentChangeWholeDocument& lhs,
                const TextDocumentContentChangeWholeDocument& rhs);
bool operator!=(const TextDocumentContentChangeWholeDocument& lhs,
                const TextDocumentContentChangeWholeDocument& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentContentChangeWholeDocument& out);
Result<const json::Value*> Encode(const TextDocumentContentChangeWholeDocument& in,
                                  json::Builder& b);

bool operator==(const MarkedStringWithLanguage& lhs, const MarkedStringWithLanguage& rhs);
bool operator!=(const MarkedStringWithLanguage& lhs, const MarkedStringWithLanguage& rhs);
Result<SuccessType> Decode(const json::Value& v, MarkedStringWithLanguage& out);
Result<const json::Value*> Encode(const MarkedStringWithLanguage& in, json::Builder& b);

bool operator==(const NotebookCellTextDocumentFilter& lhs,
                const NotebookCellTextDocumentFilter& rhs);
bool operator!=(const NotebookCellTextDocumentFilter& lhs,
                const NotebookCellTextDocumentFilter& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookCellTextDocumentFilter& out);
Result<const json::Value*> Encode(const NotebookCellTextDocumentFilter& in, json::Builder& b);

bool operator==(const RelativePattern& lhs, const RelativePattern& rhs);
bool operator!=(const RelativePattern& lhs, const RelativePattern& rhs);
Result<SuccessType> Decode(const json::Value& v, RelativePattern& out);
Result<const json::Value*> Encode(const RelativePattern& in, json::Builder& b);

bool operator==(const TextDocumentFilterLanguage& lhs, const TextDocumentFilterLanguage& rhs);
bool operator!=(const TextDocumentFilterLanguage& lhs, const TextDocumentFilterLanguage& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentFilterLanguage& out);
Result<const json::Value*> Encode(const TextDocumentFilterLanguage& in, json::Builder& b);

bool operator==(const TextDocumentFilterScheme& lhs, const TextDocumentFilterScheme& rhs);
bool operator!=(const TextDocumentFilterScheme& lhs, const TextDocumentFilterScheme& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentFilterScheme& out);
Result<const json::Value*> Encode(const TextDocumentFilterScheme& in, json::Builder& b);

bool operator==(const TextDocumentFilterPattern& lhs, const TextDocumentFilterPattern& rhs);
bool operator!=(const TextDocumentFilterPattern& lhs, const TextDocumentFilterPattern& rhs);
Result<SuccessType> Decode(const json::Value& v, TextDocumentFilterPattern& out);
Result<const json::Value*> Encode(const TextDocumentFilterPattern& in, json::Builder& b);

bool operator==(const NotebookDocumentFilterNotebookType& lhs,
                const NotebookDocumentFilterNotebookType& rhs);
bool operator!=(const NotebookDocumentFilterNotebookType& lhs,
                const NotebookDocumentFilterNotebookType& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentFilterNotebookType& out);
Result<const json::Value*> Encode(const NotebookDocumentFilterNotebookType& in, json::Builder& b);

bool operator==(const NotebookDocumentFilterScheme& lhs, const NotebookDocumentFilterScheme& rhs);
bool operator!=(const NotebookDocumentFilterScheme& lhs, const NotebookDocumentFilterScheme& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentFilterScheme& out);
Result<const json::Value*> Encode(const NotebookDocumentFilterScheme& in, json::Builder& b);

bool operator==(const NotebookDocumentFilterPattern& lhs, const NotebookDocumentFilterPattern& rhs);
bool operator!=(const NotebookDocumentFilterPattern& lhs, const NotebookDocumentFilterPattern& rhs);
Result<SuccessType> Decode(const json::Value& v, NotebookDocumentFilterPattern& out);
Result<const json::Value*> Encode(const NotebookDocumentFilterPattern& in, json::Builder& b);

////////////////////////////////////////////////////////////////////////////////
// Requests
////////////////////////////////////////////////////////////////////////////////

/// A request to resolve the implementation locations of a symbol at a given text document position.
/// The request's parameter is of type TextDocumentPositionParams the response is of type Definition
/// or a Thenable that resolves to such.
struct TextDocumentImplementationRequest : lsp::ImplementationParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/implementation";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::Definition, std::vector<lsp::DefinitionLink>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to resolve the type definition locations of a symbol at a given text document
/// position. The request's parameter is of type TextDocumentPositionParams the response is of type
/// Definition or a Thenable that resolves to such.
struct TextDocumentTypeDefinitionRequest : lsp::TypeDefinitionParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/typeDefinition";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::Definition, std::vector<lsp::DefinitionLink>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// The `workspace/workspaceFolders` is sent from the server to the client to fetch the open
/// workspace folders.
struct WorkspaceWorkspaceFoldersRequest {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/workspaceFolders";

    /// Does the request take parameters?
    static constexpr bool kHasParams = false;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::WorkspaceFolder>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// The 'workspace/configuration' request is sent from the server to the client to fetch a certain
/// configuration setting. This pull model replaces the old push model were the client signaled
/// configuration change via an event. If the server still needs to react to configuration changes
/// (since the server caches the result of `workspace/configuration` requests) the server should
/// register for an empty configuration change event and empty the cache if such an event is
/// received.
struct WorkspaceConfigurationRequest : lsp::ConfigurationParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/configuration";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = std::vector<lsp::LSPAny>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to list all color symbols found in a given text document. The request's parameter is
/// of type DocumentColorParams the response is of type ColorInformation ColorInformation[] or a
/// Thenable that resolves to such.
struct TextDocumentDocumentColorRequest : lsp::DocumentColorParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/documentColor";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = std::vector<lsp::ColorInformation>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to list all presentation for a color. The request's parameter is of type
/// ColorPresentationParams the response is of type ColorInformation ColorInformation[] or a
/// Thenable that resolves to such.
struct TextDocumentColorPresentationRequest : lsp::ColorPresentationParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/colorPresentation";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = std::vector<lsp::ColorPresentation>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to provide folding ranges in a document. The request's parameter is of type
/// FoldingRangeParams, the response is of type FoldingRangeList or a Thenable that resolves to
/// such.
struct TextDocumentFoldingRangeRequest : lsp::FoldingRangeParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/foldingRange";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::FoldingRange>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// @since 3.18.0
///
/// Proposed in:
struct WorkspaceFoldingRangeRefreshRequest {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/foldingRange/refresh";

    /// Does the request take parameters?
    static constexpr bool kHasParams = false;

    /// The result success type of the request
    using SuccessType = Null;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to resolve the type definition locations of a symbol at a given text document
/// position. The request's parameter is of type TextDocumentPositionParams the response is of type
/// Declaration or a typed array of DeclarationLink or a Thenable that resolves to such.
struct TextDocumentDeclarationRequest : lsp::DeclarationParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/declaration";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::Declaration, std::vector<lsp::DeclarationLink>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to provide selection ranges in a document. The request's parameter is of type
/// SelectionRangeParams, the response is of type SelectionRange SelectionRange[] or a Thenable that
/// resolves to such.
struct TextDocumentSelectionRangeRequest : lsp::SelectionRangeParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/selectionRange";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::SelectionRange>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// The `window/workDoneProgress/create` request is sent from the server to the client to initiate
/// progress reporting from the server.
struct WindowWorkDoneProgressCreateRequest : lsp::WorkDoneProgressCreateParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "window/workDoneProgress/create";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = Null;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to result a `CallHierarchyItem` in a document at a given position. Can be used as an
/// input to an incoming or outgoing call hierarchy.
///
/// @since 3.16.0
struct TextDocumentPrepareCallHierarchyRequest : lsp::CallHierarchyPrepareParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/prepareCallHierarchy";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::CallHierarchyItem>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to resolve the incoming calls for a given `CallHierarchyItem`.
///
/// @since 3.16.0
struct CallHierarchyIncomingCallsRequest : lsp::CallHierarchyIncomingCallsParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "callHierarchy/incomingCalls";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::CallHierarchyIncomingCall>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to resolve the outgoing calls for a given `CallHierarchyItem`.
///
/// @since 3.16.0
struct CallHierarchyOutgoingCallsRequest : lsp::CallHierarchyOutgoingCallsParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "callHierarchy/outgoingCalls";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::CallHierarchyOutgoingCall>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// @since 3.16.0
struct TextDocumentSemanticTokensFullRequest : lsp::SemanticTokensParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/semanticTokens/full";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::SemanticTokens, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// @since 3.16.0
struct TextDocumentSemanticTokensFullDeltaRequest : lsp::SemanticTokensDeltaParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/semanticTokens/full/delta";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::SemanticTokens, lsp::SemanticTokensDelta, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// @since 3.16.0
struct TextDocumentSemanticTokensRangeRequest : lsp::SemanticTokensRangeParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/semanticTokens/range";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::SemanticTokens, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// @since 3.16.0
struct WorkspaceSemanticTokensRefreshRequest {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/semanticTokens/refresh";

    /// Does the request take parameters?
    static constexpr bool kHasParams = false;

    /// The result success type of the request
    using SuccessType = Null;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to show a document. This request might open an external program depending on the value
/// of the URI to open. For example a request to open `https://code.visualstudio.com/` will very
/// likely open the URI in a WEB browser.
///
/// @since 3.16.0
struct WindowShowDocumentRequest : lsp::ShowDocumentParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "window/showDocument";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = lsp::ShowDocumentResult;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to provide ranges that can be edited together.
///
/// @since 3.16.0
struct TextDocumentLinkedEditingRangeRequest : lsp::LinkedEditingRangeParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/linkedEditingRange";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::LinkedEditingRanges, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// The will create files request is sent from the client to the server before files are actually
/// created as long as the creation is triggered from within the client. The request can return a
/// `WorkspaceEdit` which will be applied to workspace before the files are created. Hence the
/// `WorkspaceEdit` can not manipulate the content of the file to be created.
///
/// @since 3.16.0
struct WorkspaceWillCreateFilesRequest : lsp::CreateFilesParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/willCreateFiles";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::WorkspaceEdit, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// The will rename files request is sent from the client to the server before files are actually
/// renamed as long as the rename is triggered from within the client.
///
/// @since 3.16.0
struct WorkspaceWillRenameFilesRequest : lsp::RenameFilesParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/willRenameFiles";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::WorkspaceEdit, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// The did delete files notification is sent from the client to the server when files were deleted
/// from within the client.
///
/// @since 3.16.0
struct WorkspaceWillDeleteFilesRequest : lsp::DeleteFilesParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/willDeleteFiles";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::WorkspaceEdit, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to get the moniker of a symbol at a given text document position. The request
/// parameter is of type TextDocumentPositionParams. The response is of type Moniker Moniker[] or
/// `null`.
struct TextDocumentMonikerRequest : lsp::MonikerParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/moniker";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::Moniker>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to result a `TypeHierarchyItem` in a document at a given position. Can be used as an
/// input to a subtypes or supertypes type hierarchy.
///
/// @since 3.17.0
struct TextDocumentPrepareTypeHierarchyRequest : lsp::TypeHierarchyPrepareParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/prepareTypeHierarchy";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::TypeHierarchyItem>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to resolve the supertypes for a given `TypeHierarchyItem`.
///
/// @since 3.17.0
struct TypeHierarchySupertypesRequest : lsp::TypeHierarchySupertypesParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "typeHierarchy/supertypes";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::TypeHierarchyItem>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to resolve the subtypes for a given `TypeHierarchyItem`.
///
/// @since 3.17.0
struct TypeHierarchySubtypesRequest : lsp::TypeHierarchySubtypesParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "typeHierarchy/subtypes";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::TypeHierarchyItem>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to provide inline values in a document. The request's parameter is of type
/// InlineValueParams, the response is of type InlineValue InlineValue[] or a Thenable that resolves
/// to such.
///
/// @since 3.17.0
struct TextDocumentInlineValueRequest : lsp::InlineValueParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/inlineValue";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::InlineValue>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// @since 3.17.0
struct WorkspaceInlineValueRefreshRequest {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/inlineValue/refresh";

    /// Does the request take parameters?
    static constexpr bool kHasParams = false;

    /// The result success type of the request
    using SuccessType = Null;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to provide inlay hints in a document. The request's parameter is of type
/// InlayHintsParams, the response is of type InlayHint InlayHint[] or a Thenable that resolves to
/// such.
///
/// @since 3.17.0
struct TextDocumentInlayHintRequest : lsp::InlayHintParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/inlayHint";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::InlayHint>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to resolve additional properties for an inlay hint. The request's parameter is of type
/// InlayHint, the response is of type InlayHint or a Thenable that resolves to such.
///
/// @since 3.17.0
struct InlayHintResolveRequest : lsp::InlayHint {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "inlayHint/resolve";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = lsp::InlayHint;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// @since 3.17.0
struct WorkspaceInlayHintRefreshRequest {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/inlayHint/refresh";

    /// Does the request take parameters?
    static constexpr bool kHasParams = false;

    /// The result success type of the request
    using SuccessType = Null;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// The document diagnostic request definition.
///
/// @since 3.17.0
struct TextDocumentDiagnosticRequest : lsp::DocumentDiagnosticParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/diagnostic";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = lsp::DocumentDiagnosticReport;
    /// The result error type of the request
    using FailureType = lsp::DiagnosticServerCancellationData;
    /// The result type (success or failure) of the request
    using ResultType = Result<SuccessType, FailureType>;
};

/// The workspace diagnostic request definition.
///
/// @since 3.17.0
struct WorkspaceDiagnosticRequest : lsp::WorkspaceDiagnosticParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/diagnostic";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = lsp::WorkspaceDiagnosticReport;
    /// The result error type of the request
    using FailureType = lsp::DiagnosticServerCancellationData;
    /// The result type (success or failure) of the request
    using ResultType = Result<SuccessType, FailureType>;
};

/// The diagnostic refresh request definition.
///
/// @since 3.17.0
struct WorkspaceDiagnosticRefreshRequest {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/diagnostic/refresh";

    /// Does the request take parameters?
    static constexpr bool kHasParams = false;

    /// The result success type of the request
    using SuccessType = Null;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to provide inline completions in a document. The request's parameter is of type
/// InlineCompletionParams, the response is of type InlineCompletion InlineCompletion[] or a
/// Thenable that resolves to such.
///
/// @since 3.18.0
///
/// Proposed in:
struct TextDocumentInlineCompletionRequest : lsp::InlineCompletionParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/inlineCompletion";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType =
        OneOf<lsp::InlineCompletionList, std::vector<lsp::InlineCompletionItem>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// The `client/registerCapability` request is sent from the server to the client to register a new
/// capability handler on the client side.
struct ClientRegisterCapabilityRequest : lsp::RegistrationParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "client/registerCapability";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = Null;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// The `client/unregisterCapability` request is sent from the server to the client to unregister a
/// previously registered capability handler on the client side.
struct ClientUnregisterCapabilityRequest : lsp::UnregistrationParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "client/unregisterCapability";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = Null;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// The initialize request is sent from the client to the server. It is sent once as the request
/// after starting up the server. The requests parameter is of type InitializeParams the response if
/// of type InitializeResult of a Thenable that resolves to such.
struct InitializeRequest : lsp::InitializeParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "initialize";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = lsp::InitializeResult;
    /// The result error type of the request
    using FailureType = lsp::InitializeError;
    /// The result type (success or failure) of the request
    using ResultType = Result<SuccessType, FailureType>;
};

/// A shutdown request is sent from the client to the server. It is sent once when the client
/// decides to shutdown the server. The only notification that is sent after a shutdown request is
/// the exit event.
struct ShutdownRequest {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "shutdown";

    /// Does the request take parameters?
    static constexpr bool kHasParams = false;

    /// The result success type of the request
    using SuccessType = Null;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// The show message request is sent from the server to the client to show a message and a set of
/// options actions to the user.
struct WindowShowMessageRequestRequest : lsp::ShowMessageRequestParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "window/showMessageRequest";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::MessageActionItem, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A document will save request is sent from the client to the server before the document is
/// actually saved. The request can return an array of TextEdits which will be applied to the text
/// document before it is saved. Please note that clients might drop results if computing the text
/// edits took too long or if a server constantly fails on this request. This is done to keep the
/// save fast and reliable.
struct TextDocumentWillSaveWaitUntilRequest : lsp::WillSaveTextDocumentParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/willSaveWaitUntil";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::TextEdit>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// Request to request completion at a given text document position. The request's parameter is of
/// type TextDocumentPosition the response is of type CompletionItem CompletionItem[] or
/// CompletionList or a Thenable that resolves to such. The request can delay the computation of the
/// CompletionItem.detail `detail` and CompletionItem.documentation `documentation` properties to
/// the `completionItem/resolve` request. However, properties that are needed for the initial
/// sorting and filtering, like `sortText`, `filterText`, `insertText`, and `textEdit`, must not be
/// changed during resolve.
struct TextDocumentCompletionRequest : lsp::CompletionParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/completion";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::CompletionItem>, lsp::CompletionList, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// Request to resolve additional information for a given completion item.The request's parameter is
/// of type CompletionItem the response is of type CompletionItem or a Thenable that resolves to
/// such.
struct CompletionItemResolveRequest : lsp::CompletionItem {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "completionItem/resolve";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = lsp::CompletionItem;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// Request to request hover information at a given text document position. The request's parameter
/// is of type TextDocumentPosition the response is of type Hover or a Thenable that resolves to
/// such.
struct TextDocumentHoverRequest : lsp::HoverParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/hover";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::Hover, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// No documentation available
struct TextDocumentSignatureHelpRequest : lsp::SignatureHelpParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/signatureHelp";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::SignatureHelp, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to resolve the definition location of a symbol at a given text document position. The
/// request's parameter is of type TextDocumentPosition the response is of either type Definition or
/// a typed array of DefinitionLink or a Thenable that resolves to such.
struct TextDocumentDefinitionRequest : lsp::DefinitionParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/definition";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::Definition, std::vector<lsp::DefinitionLink>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to resolve project-wide references for the symbol denoted by the given text document
/// position. The request's parameter is of type ReferenceParams the response is of type Location
/// Location[] or a Thenable that resolves to such.
struct TextDocumentReferencesRequest : lsp::ReferenceParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/references";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::Location>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// Request to resolve a DocumentHighlight for a given text document position. The request's
/// parameter is of type TextDocumentPosition the request response is an array of type
/// DocumentHighlight or a Thenable that resolves to such.
struct TextDocumentDocumentHighlightRequest : lsp::DocumentHighlightParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/documentHighlight";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::DocumentHighlight>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to list all symbols found in a given text document. The request's parameter is of type
/// TextDocumentIdentifier the response is of type SymbolInformation SymbolInformation[] or a
/// Thenable that resolves to such.
struct TextDocumentDocumentSymbolRequest : lsp::DocumentSymbolParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/documentSymbol";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType =
        OneOf<std::vector<lsp::SymbolInformation>, std::vector<lsp::DocumentSymbol>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to provide commands for the given text document and range.
struct TextDocumentCodeActionRequest : lsp::CodeActionParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/codeAction";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<OneOf<lsp::Command, lsp::CodeAction>>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// Request to resolve additional information for a given code action.The request's parameter is of
/// type CodeAction the response is of type CodeAction or a Thenable that resolves to such.
struct CodeActionResolveRequest : lsp::CodeAction {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "codeAction/resolve";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = lsp::CodeAction;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to list project-wide symbols matching the query string given by the
/// WorkspaceSymbolParams. The response is of type SymbolInformation SymbolInformation[] or a
/// Thenable that resolves to such.
///
/// @since 3.17.0 - support for WorkspaceSymbol in the returned data. Clients need to advertise
/// support for WorkspaceSymbols via the client capability `workspace.symbol.resolveSupport`.
struct WorkspaceSymbolRequest : lsp::WorkspaceSymbolParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/symbol";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType =
        OneOf<std::vector<lsp::SymbolInformation>, std::vector<lsp::WorkspaceSymbol>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to resolve the range inside the workspace symbol's location.
///
/// @since 3.17.0
struct WorkspaceSymbolResolveRequest : lsp::WorkspaceSymbol {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspaceSymbol/resolve";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = lsp::WorkspaceSymbol;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to provide code lens for the given text document.
struct TextDocumentCodeLensRequest : lsp::CodeLensParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/codeLens";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::CodeLens>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to resolve a command for a given code lens.
struct CodeLensResolveRequest : lsp::CodeLens {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "codeLens/resolve";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = lsp::CodeLens;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to refresh all code actions
///
/// @since 3.16.0
struct WorkspaceCodeLensRefreshRequest {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/codeLens/refresh";

    /// Does the request take parameters?
    static constexpr bool kHasParams = false;

    /// The result success type of the request
    using SuccessType = Null;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to provide document links
struct TextDocumentDocumentLinkRequest : lsp::DocumentLinkParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/documentLink";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::DocumentLink>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// Request to resolve additional information for a given document link. The request's parameter is
/// of type DocumentLink the response is of type DocumentLink or a Thenable that resolves to such.
struct DocumentLinkResolveRequest : lsp::DocumentLink {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "documentLink/resolve";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = lsp::DocumentLink;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to format a whole document.
struct TextDocumentFormattingRequest : lsp::DocumentFormattingParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/formatting";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::TextEdit>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to format a range in a document.
struct TextDocumentRangeFormattingRequest : lsp::DocumentRangeFormattingParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/rangeFormatting";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::TextEdit>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to format ranges in a document.
///
/// @since 3.18.0
///
/// Proposed in:
struct TextDocumentRangesFormattingRequest : lsp::DocumentRangesFormattingParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/rangesFormatting";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::TextEdit>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to format a document on type.
struct TextDocumentOnTypeFormattingRequest : lsp::DocumentOnTypeFormattingParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/onTypeFormatting";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<std::vector<lsp::TextEdit>, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to rename a symbol.
struct TextDocumentRenameRequest : lsp::RenameParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/rename";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::WorkspaceEdit, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request to test and perform the setup necessary for a rename.
///
/// @since 3.16 - support for default behavior
struct TextDocumentPrepareRenameRequest : lsp::PrepareRenameParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "textDocument/prepareRename";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::PrepareRenameResult, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request send from the client to the server to execute a command. The request might return a
/// workspace edit which the client will apply to the workspace.
struct WorkspaceExecuteCommandRequest : lsp::ExecuteCommandParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/executeCommand";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = OneOf<lsp::LSPAny, Null>;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

/// A request sent from the server to the client to modified certain resources.
struct WorkspaceApplyEditRequest : lsp::ApplyWorkspaceEditParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kRequest;

    /// The LSP name for the request
    static constexpr std::string_view kMethod = "workspace/applyEdit";

    /// Does the request take parameters?
    static constexpr bool kHasParams = true;

    /// The result success type of the request
    using SuccessType = lsp::ApplyWorkspaceEditResult;
    /// The result error type of the request
    using FailureType = void;
    /// The result type (success or failure) of the request
    using ResultType = SuccessType;
};

////////////////////////////////////////////////////////////////////////////////
// Notifications
////////////////////////////////////////////////////////////////////////////////

/// The `workspace/didChangeWorkspaceFolders` notification is sent from the client to the server
/// when the workspace folder configuration changes.
struct WorkspaceDidChangeWorkspaceFoldersNotification : lsp::DidChangeWorkspaceFoldersParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "workspace/didChangeWorkspaceFolders";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The `window/workDoneProgress/cancel` notification is sent from the client to the server to
/// cancel a progress initiated on the server side.
struct WindowWorkDoneProgressCancelNotification : lsp::WorkDoneProgressCancelParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "window/workDoneProgress/cancel";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The did create files notification is sent from the client to the server when files were created
/// from within the client.
///
/// @since 3.16.0
struct WorkspaceDidCreateFilesNotification : lsp::CreateFilesParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "workspace/didCreateFiles";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The did rename files notification is sent from the client to the server when files were renamed
/// from within the client.
///
/// @since 3.16.0
struct WorkspaceDidRenameFilesNotification : lsp::RenameFilesParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "workspace/didRenameFiles";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The will delete files request is sent from the client to the server before files are actually
/// deleted as long as the deletion is triggered from within the client.
///
/// @since 3.16.0
struct WorkspaceDidDeleteFilesNotification : lsp::DeleteFilesParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "workspace/didDeleteFiles";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// A notification sent when a notebook opens.
///
/// @since 3.17.0
struct NotebookDocumentDidOpenNotification : lsp::DidOpenNotebookDocumentParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "notebookDocument/didOpen";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// No documentation available
struct NotebookDocumentDidChangeNotification : lsp::DidChangeNotebookDocumentParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "notebookDocument/didChange";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// A notification sent when a notebook document is saved.
///
/// @since 3.17.0
struct NotebookDocumentDidSaveNotification : lsp::DidSaveNotebookDocumentParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "notebookDocument/didSave";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// A notification sent when a notebook closes.
///
/// @since 3.17.0
struct NotebookDocumentDidCloseNotification : lsp::DidCloseNotebookDocumentParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "notebookDocument/didClose";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The initialized notification is sent from the client to the server after the client is fully
/// initialized and the server is allowed to send requests from the server to the client.
struct InitializedNotification : lsp::InitializedParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "initialized";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The exit event is sent from the client to the server to ask the server to exit its process.
struct ExitNotification {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "exit";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = false;
};

/// The configuration change notification is sent from the client to the server when the client's
/// configuration has changed. The notification contains the changed configuration as defined by the
/// language client.
struct WorkspaceDidChangeConfigurationNotification : lsp::DidChangeConfigurationParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "workspace/didChangeConfiguration";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The show message notification is sent from a server to a client to ask the client to display a
/// particular message in the user interface.
struct WindowShowMessageNotification : lsp::ShowMessageParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "window/showMessage";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The log message notification is sent from the server to the client to ask the client to log a
/// particular message.
struct WindowLogMessageNotification : lsp::LogMessageParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "window/logMessage";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The telemetry event notification is sent from the server to the client to ask the client to log
/// telemetry data.
struct TelemetryEventNotification : lsp::LSPAny {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "telemetry/event";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The document open notification is sent from the client to the server to signal newly opened text
/// documents. The document's truth is now managed by the client and the server must not try to read
/// the document's truth using the document's uri. Open in this sense means it is managed by the
/// client. It doesn't necessarily mean that its content is presented in an editor. An open
/// notification must not be sent more than once without a corresponding close notification send
/// before. This means open and close notification must be balanced and the max open count is one.
struct TextDocumentDidOpenNotification : lsp::DidOpenTextDocumentParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "textDocument/didOpen";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The document change notification is sent from the client to the server to signal changes to a
/// text document.
struct TextDocumentDidChangeNotification : lsp::DidChangeTextDocumentParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "textDocument/didChange";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The document close notification is sent from the client to the server when the document got
/// closed in the client. The document's truth now exists where the document's uri points to (e.g.
/// if the document's uri is a file uri the truth now exists on disk). As with the open notification
/// the close notification is about managing the document's content. Receiving a close notification
/// doesn't mean that the document was open in an editor before. A close notification requires a
/// previous open notification to be sent.
struct TextDocumentDidCloseNotification : lsp::DidCloseTextDocumentParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "textDocument/didClose";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The document save notification is sent from the client to the server when the document got saved
/// in the client.
struct TextDocumentDidSaveNotification : lsp::DidSaveTextDocumentParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "textDocument/didSave";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// A document will save notification is sent from the client to the server before the document is
/// actually saved.
struct TextDocumentWillSaveNotification : lsp::WillSaveTextDocumentParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "textDocument/willSave";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// The watched files notification is sent from the client to the server when the client detects
/// changes to file watched by the language client.
struct WorkspaceDidChangeWatchedFilesNotification : lsp::DidChangeWatchedFilesParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "workspace/didChangeWatchedFiles";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// Diagnostics notification are sent from the server to the client to signal results of validation
/// runs.
struct TextDocumentPublishDiagnosticsNotification : lsp::PublishDiagnosticsParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "textDocument/publishDiagnostics";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// No documentation available
struct SetTraceNotification : lsp::SetTraceParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "$/setTrace";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// No documentation available
struct LogTraceNotification : lsp::LogTraceParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "$/logTrace";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// No documentation available
struct CancelRequestNotification : lsp::CancelParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "$/cancelRequest";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

/// No documentation available
struct ProgressNotification : lsp::ProgressParams {
    /// The LSP message type
    static constexpr MessageKind kMessageKind = MessageKind::kNotification;

    /// The LSP name for the notification
    static constexpr std::string_view kMethod = "$/progress";

    /// Does the Notification take parameters?
    static constexpr bool kHasParams = true;
};

}  // namespace langsvr::lsp

#endif  // LANGSVR_LSP_LSP_H_
